From 1f4234a9c26d6470ebdc33eceac39a45640ec9e2 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:20:46 +0800
Subject: [PATCH 01/27] Add ConstantExpectedAnalyzer
---
.../CSharpConstantExpectedAnalyzer.cs | 61 +++
.../MicrosoftNetCoreAnalyzersResources.resx | 39 ++
...onstantExpectedAnalyzer.UnmanagedHelper.cs | 435 ++++++++++++++++
.../Performance/ConstantExpectedAnalyzer.cs | 490 ++++++++++++++++++
.../MicrosoftNetCoreAnalyzersResources.cs.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.de.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.es.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.fr.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.it.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.ja.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.ko.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.pl.xlf | 65 +++
...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.ru.xlf | 65 +++
.../MicrosoftNetCoreAnalyzersResources.tr.xlf | 65 +++
...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 65 +++
...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 65 +++
.../Performance/ConstantExpectedTests.cs | 470 +++++++++++++++++
18 files changed, 2340 insertions(+)
create mode 100644 src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
new file mode 100644
index 0000000000..1698498f50
--- /dev/null
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.NetCore.Analyzers.Performance;
+
+namespace Microsoft.NetCore.CSharp.Analyzers.Performance
+{
+ [DiagnosticAnalyzer(LanguageNames.CSharp)]
+ internal sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
+ {
+ private static readonly CSharpDiagnosticHelper s_diagnosticHelper = new();
+ private readonly IdentifierNameSyntax _constantExpectedIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpected);
+ private readonly IdentifierNameSyntax _constantExpectedAttributeIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedAttribute);
+
+ protected override DiagnosticHelper Helper => s_diagnosticHelper;
+
+ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext context)
+ {
+ context.RegisterSyntaxNodeAction(context => OnAttributeNode(context), SyntaxKind.Attribute);
+ }
+ private void OnAttributeNode(SyntaxNodeAnalysisContext context)
+ {
+ var attributeSyntax = (AttributeSyntax)context.Node;
+ var sm = context.SemanticModel;
+ if (!attributeSyntax.Name.IsEquivalentTo(_constantExpectedIdentifier) && !attributeSyntax.Name.IsEquivalentTo(_constantExpectedAttributeIdentifier))
+ {
+ return;
+ }
+ var parameter = (ParameterSyntax)attributeSyntax.Parent.Parent;
+ var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter);
+
+ OnParameterWithConstantExecptedAttribute(parameterSymbol, context.ReportDiagnostic);
+ }
+
+ private sealed class CSharpDiagnosticHelper : DiagnosticHelper
+ {
+ private readonly IdentifierNameSyntax _constantExpectedMinIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName("Min");
+ private readonly IdentifierNameSyntax _constantExpectedMaxIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName("Max");
+
+ public override Location? GetMaxLocation(SyntaxNode attributeNode) => GetArgumentLocation(attributeNode, _constantExpectedMaxIdentifier);
+
+ public override Location? GetMinLocation(SyntaxNode attributeNode) => GetArgumentLocation(attributeNode, _constantExpectedMinIdentifier);
+
+ private static Location? GetArgumentLocation(SyntaxNode attributeNode, IdentifierNameSyntax targetNameSyntax)
+ {
+ var attributeSyntax = (AttributeSyntax)attributeNode;
+ if (attributeSyntax.ArgumentList is null)
+ {
+ return null;
+ }
+ var targetArg = attributeSyntax.ArgumentList.Arguments.FirstOrDefault(arg => arg.NameEquals.Name.IsEquivalentTo(targetNameSyntax, true));
+ return targetArg?.GetLocation();
+ }
+ }
+ }
+}
+;
\ No newline at end of file
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index 8d5aa05b65..8b025eec2b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1834,4 +1834,43 @@
'{0}' uses the preview type '{1}' and needs to opt into preview features. See {2} for more information.
+
+ Incorerct use of ConstantExpectedAttribute
+
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+ Constant is expected for the parameter
+
+
+ The parameter expects a constant for best performance.
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+ The Min/Max condition can only be null for '{0}' types.
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+ The Min and Max conditions are inverted.
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+ The argument should be a constant.
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
\ No newline at end of file
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
new file mode 100644
index 0000000000..8236b6b66e
--- /dev/null
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
@@ -0,0 +1,435 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
+using Analyzer.Utilities.Extensions;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Operations;
+
+namespace Microsoft.NetCore.Analyzers.Performance
+{
+ public abstract partial class ConstantExpectedAnalyzer
+ {
+ private sealed class UnmanagedHelper where T : unmanaged
+ {
+ private static readonly UnmanagedHelper.ConstantExpectedParameterFactory? _instance;
+ private static UnmanagedHelper.ConstantExpectedParameterFactory Instance => _instance ?? throw new InvalidOperationException("unsupported type");
+
+ static UnmanagedHelper()
+ {
+ if (typeof(T) == typeof(long))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertInt64, TryTransformInt64);
+ _instance = new UnmanagedHelper.ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ else if (typeof(T) == typeof(ulong))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertUInt64, TryTransformUInt64);
+ _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ else if (typeof(T) == typeof(float))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertSingle, TryTransformSingle);
+ _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ else if (typeof(T) == typeof(double))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertDouble, TryTransformDouble);
+ _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ else if (typeof(T) == typeof(char))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertChar, TryTransformChar);
+ _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ else if (typeof(T) == typeof(bool))
+ {
+ var helper = new UnmanagedHelper.TransformHelper(TryConvertBoolean, TryTransformBoolean);
+ _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ }
+ }
+
+ public static bool TryCreate(IParameterSymbol parameterSymbol, AttributeData attributeData, T typeMin, T typeMax, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
+ => Instance.TryCreate(parameterSymbol, attributeData, typeMin, typeMax, out parameter);
+ public static bool Validate(IParameterSymbol parameterSymbol, AttributeData attributeData, T typeMin, T typeMax, DiagnosticHelper diagnosticHelper, out ImmutableArray diagnostics)
+ => Instance.Validate(parameterSymbol, attributeData, typeMin, typeMax, diagnosticHelper, out diagnostics);
+
+ public delegate bool TryTransform(object constant, out T value, out bool isInvalid);
+ public delegate bool TryConvert(object? constant, out T value);
+ public sealed class TransformHelper
+ {
+ private readonly TryTransform _tryTransform;
+ private readonly TryConvert _convert;
+
+ public TransformHelper(TryConvert convert, TryTransform tryTransform)
+ {
+ _convert = convert;
+ _tryTransform = tryTransform;
+ }
+
+ public bool IsLessThan(T operand1, T operand2) => Comparer.Default.Compare(operand1, operand2) < 0;
+ public bool TryTransformMin(object constant, out T value, ref ErrorKind errorFlags)
+ {
+ if (_tryTransform(constant, out value, out bool isInvalid))
+ {
+ return true;
+ }
+
+ if (isInvalid)
+ {
+ errorFlags |= ErrorKind.MinIsIncompatible;
+ }
+ else
+ {
+ errorFlags |= ErrorKind.MinIsOutOfRange;
+ }
+ return false;
+ }
+
+ public bool TryTransformMax(object constant, out T value, ref ErrorKind errorFlags)
+ {
+ if (_tryTransform(constant, out value, out bool isInvalid))
+ {
+ return true;
+ }
+
+ if (isInvalid)
+ {
+ errorFlags |= ErrorKind.MaxIsIncompatible;
+ }
+ else
+ {
+ errorFlags |= ErrorKind.MaxIsOutOfRange;
+ }
+ return false;
+ }
+ public bool TryConvert(object? val, out T value) => _convert(val, out value);
+ }
+
+ public sealed class ConstantExpectedParameterFactory
+ {
+ private readonly TransformHelper _helper;
+
+ public ConstantExpectedParameterFactory(TransformHelper helper)
+ {
+ _helper = helper;
+ }
+ public bool Validate(IParameterSymbol parameterSymbol, AttributeData attributeData, T typeMin, T typeMax, DiagnosticHelper diagnosticHelper, out ImmutableArray diagnostics)
+ {
+ if (!IsValidMinMax(attributeData, typeMin, typeMax, out _, out _, out ErrorKind errorFlags))
+ {
+ diagnostics = diagnosticHelper.GetError(errorFlags, parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax(), typeMin.ToString(), typeMax.ToString());
+ return false;
+ }
+
+ diagnostics = ImmutableArray.Empty;
+ return true;
+ }
+
+ public bool TryCreate(IParameterSymbol parameterSymbol, AttributeData attributeData, T typeMin, T typeMax, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
+ {
+ if (!IsValidMinMax(attributeData, typeMin, typeMax, out T minValue, out T maxValue, out _))
+ {
+ parameter = null;
+ return false;
+ }
+
+ parameter = new UnmanagedConstantExpectedParameter(parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax(), minValue, maxValue, _helper);
+ return true;
+ }
+
+ private bool IsValidMinMax(AttributeData attributeData, T typeMin, T typeMax, out T minValue, out T maxValue, out ErrorKind errorFlags)
+ {
+ minValue = typeMin;
+ maxValue = typeMax;
+ (object? min, object? max) = GetAttributeConstants(attributeData);
+ errorFlags = ErrorKind.None;
+ if (min is not null && _helper.TryTransformMin(min, out minValue, ref errorFlags))
+ {
+ if (_helper.IsLessThan(minValue, typeMin) || _helper.IsLessThan(typeMax, minValue))
+ {
+ errorFlags |= ErrorKind.MinIsOutOfRange;
+ }
+ }
+
+ if (max is not null && _helper.TryTransformMax(max, out maxValue, ref errorFlags))
+ {
+ if (_helper.IsLessThan(maxValue, typeMin) || _helper.IsLessThan(typeMax, maxValue))
+ {
+ errorFlags |= ErrorKind.MaxIsOutOfRange;
+ }
+ }
+
+ if (errorFlags != ErrorKind.None)
+ {
+ return false;
+ }
+
+ if (_helper.IsLessThan(maxValue, minValue))
+ {
+ errorFlags = ErrorKind.MinMaxInverted;
+ return false;
+ }
+ return true;
+ }
+ }
+
+ public sealed class UnmanagedConstantExpectedParameter : ConstantExpectedParameter
+ {
+ private readonly TransformHelper _helper;
+ public UnmanagedConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax, T min, T max, TransformHelper helper) : base(parameter, attributeSyntax)
+ {
+ Min = min;
+ Max = max;
+ _helper = helper;
+ }
+
+ public T Min { get; }
+ public T Max { get; }
+
+ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ {
+ if (Parameter.Type.SpecialType != subsetCandidate.Parameter.Type.SpecialType ||
+ subsetCandidate is not UnmanagedConstantExpectedParameter subsetCandidateTParameter)
+ {
+ validationDiagnostics = Diagnostic.Create(AttributeNotSameTypeRule, subsetCandidate.AttributeSyntax.GetLocation(), Parameter.Type.ToDisplayString());
+ return false;
+ }
+
+ if (!_helper.IsLessThan(subsetCandidateTParameter.Min, Min) && !_helper.IsLessThan(Max, subsetCandidateTParameter.Max))
+ {
+ //within range
+ validationDiagnostics = null;
+ return true;
+ }
+ validationDiagnostics = Diagnostic.Create(AttributeOutOfBoundsRule, subsetCandidateTParameter.AttributeSyntax.GetLocation(), Min.ToString(), Max.ToString());
+ return false;
+ }
+
+ public override bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ {
+ if (_helper.TryConvert(constant, out T value))
+ {
+ if (!_helper.IsLessThan(value, Min) && !_helper.IsLessThan(Max, value))
+ {
+ validationDiagnostics = null;
+ return true;
+ }
+ }
+
+ validationDiagnostics = argument.CreateDiagnostic(ConstantOutOfBoundsRule, Min.ToString(), Max.ToString());
+ return false;
+ }
+ }
+ }
+
+ private static bool TryConvertSignedInteger(object constant, out long integer)
+ {
+ try
+ {
+ if (constant is string or bool)
+ {
+ integer = default;
+ return false;
+ }
+ integer = Convert.ToInt64(constant);
+ }
+ catch
+ {
+ integer = default;
+ return false;
+ }
+ return true;
+ }
+ private static bool TryConvertUnsignedInteger(object constant, out ulong integer)
+ {
+ try
+ {
+ if (constant is string or bool)
+ {
+ integer = default;
+ return false;
+ }
+ integer = Convert.ToUInt64(constant);
+ }
+ catch
+ {
+ integer = default;
+ return false;
+ }
+ return true;
+ }
+
+ private static bool TryConvertInt64(object? constant, out long value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = Convert.ToInt64(constant);
+ return true;
+ }
+
+ private static bool TryTransformInt64(object constant, out long value, out bool isInvalid)
+ {
+ bool isValidSigned = TryConvertSignedInteger(constant, out value);
+ isInvalid = false;
+ if (!isValidSigned)
+ {
+ bool isValidUnsigned = TryConvertUnsignedInteger(constant, out _);
+ if (!isValidUnsigned)
+ {
+ isInvalid = true;
+ }
+ }
+
+ return isValidSigned;
+ }
+ private static bool TryConvertUInt64(object? constant, out ulong value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = Convert.ToUInt64(constant);
+ return true;
+ }
+ private static bool TryTransformUInt64(object constant, out ulong value, out bool isInvalid)
+ {
+ bool isValidUnsigned = TryConvertUnsignedInteger(constant, out value);
+ isInvalid = false;
+ if (!isValidUnsigned)
+ {
+ bool isValidSigned = TryConvertSignedInteger(constant, out _);
+ if (!isValidSigned)
+ {
+ isInvalid = true;
+ }
+ }
+ return isValidUnsigned;
+ }
+
+ private static bool TryTransformChar(object constant, out char value, out bool isInvalid)
+ {
+ try
+ {
+ if (constant is string or bool)
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ value = Convert.ToChar(constant);
+ }
+ catch
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ isInvalid = false;
+ return true;
+ }
+ private static bool TryConvertChar(object? constant, out char value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = Convert.ToChar(constant);
+ return true;
+ }
+
+ private static bool TryTransformBoolean(object constant, out bool value, out bool isInvalid)
+ {
+ if (constant is bool b)
+ {
+ value = b;
+ isInvalid = false;
+ return true;
+ }
+ isInvalid = true;
+ value = default;
+ return false;
+ }
+ private static bool TryConvertBoolean(object? constant, out bool value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = (bool)constant;
+ return true;
+ }
+
+ private static bool TryTransformSingle(object constant, out float value, out bool isInvalid)
+ {
+ try
+ {
+ if (constant is string or bool)
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ value = Convert.ToSingle(constant);
+ }
+ catch
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ isInvalid = false;
+ return true;
+ }
+ private static bool TryConvertSingle(object? constant, out float value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = Convert.ToSingle(constant);
+ return true;
+ }
+
+ private static bool TryTransformDouble(object constant, out double value, out bool isInvalid)
+ {
+ try
+ {
+ if (constant is string or bool)
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ value = Convert.ToDouble(constant);
+ }
+ catch
+ {
+ value = default;
+ isInvalid = true;
+ return false;
+ }
+ isInvalid = false;
+ return true;
+ }
+ private static bool TryConvertDouble(object? constant, out double value)
+ {
+ if (constant is null)
+ {
+ value = default;
+ return false;
+ }
+ value = Convert.ToDouble(constant);
+ return true;
+ }
+ }
+}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
new file mode 100644
index 0000000000..3007649524
--- /dev/null
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -0,0 +1,490 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System;
+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.Performance
+{
+ using static MicrosoftNetCoreAnalyzersResources;
+ public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
+ {
+ internal const string CA1860 = nameof(CA1860);
+ internal const string CA1861 = nameof(CA1861);
+ protected static readonly string ConstantExpectedAttribute = nameof(ConstantExpectedAttribute);
+ protected static readonly string ConstantExpected = nameof(ConstantExpected);
+ private static readonly LocalizableString s_localizableApplicationTitle = CreateLocalizableResourceString(nameof(ConstantExpectedApplicationTitle));
+ private static readonly LocalizableString s_localizableApplicationDescription = CreateLocalizableResourceString(nameof(ConstantExpectedApplicationDescription));
+ private static readonly LocalizableString s_localizableUsageTitle = CreateLocalizableResourceString(nameof(ConstantExpectedUsageTitle));
+ private static readonly LocalizableString s_localizableUsageDescription = CreateLocalizableResourceString(nameof(ConstantExpectedUsageDescription));
+
+ internal static readonly DiagnosticDescriptor InvalidTypeRule = DiagnosticDescriptorHelper.Create(
+ CA1860,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvalidTypeMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildError,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor IncompatibleConstantTypeRule = DiagnosticDescriptorHelper.Create(
+ CA1860,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedIncompatibleConstantTypeMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildError,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor IncompatibleConstantForMinMaxRule = DiagnosticDescriptorHelper.Create(
+ CA1860,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedIncompatibleConstantMinMaxMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildError,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor InvalidBoundsRule = DiagnosticDescriptorHelper.Create(
+ CA1860,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvalidBoundsMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildError,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor InvertedRangeRule = DiagnosticDescriptorHelper.Create(
+ CA1860,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvertedRangeMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildError,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor ConstantOutOfBoundsRule = DiagnosticDescriptorHelper.Create(
+ CA1861,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedOutOfBoundsMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildWarning,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor ConstantNotConstantRule = DiagnosticDescriptorHelper.Create(
+ CA1861,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedNotConstantMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildWarning,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor AttributeOutOfBoundsRule = DiagnosticDescriptorHelper.Create(
+ CA1861,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedAttributeOutOfBoundsMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildWarning,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor AttributeNotSameTypeRule = DiagnosticDescriptorHelper.Create(
+ CA1861,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedAttributeNotSameTypeMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildWarning,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+ public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(
+ InvalidTypeRule, IncompatibleConstantTypeRule, IncompatibleConstantForMinMaxRule, InvalidBoundsRule, InvertedRangeRule,
+ ConstantOutOfBoundsRule, ConstantNotConstantRule, AttributeOutOfBoundsRule, AttributeNotSameTypeRule);
+
+ protected abstract DiagnosticHelper Helper { get; }
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.RegisterCompilationStartAction(context => OnCompilationStart(context));
+ }
+
+ private void OnCompilationStart(CompilationStartAnalysisContext context)
+ {
+ context.RegisterOperationAction(OnInvocation, OperationKind.Invocation);
+ RegisterAttributeSyntax(context);
+ return;
+ }
+
+ private static void OnInvocation(OperationAnalysisContext context)
+ {
+ var invocation = (IInvocationOperation)context.Operation;
+
+ foreach (var argument in invocation.Arguments)
+ {
+ if (!TryCreateConstantExpectedParameter(argument.Parameter, out var argConstantParameter))
+ {
+ continue;
+ }
+ var v = argument.Value.WalkDownConversion();
+ if (v is IParameterReferenceOperation parameterReference &&
+ TryCreateConstantExpectedParameter(parameterReference.Parameter, out var currConstantParameter))
+ {
+ if (!argConstantParameter.ValidateParameterIsWithinRange(currConstantParameter, out var parameterCheckDiagnostic))
+ {
+ context.ReportDiagnostic(parameterCheckDiagnostic);
+ }
+ continue;
+ }
+ var constantValue = v.ConstantValue;
+ if (!constantValue.HasValue)
+ {
+ var location = argument.Syntax.GetLocation();
+ context.ReportDiagnostic(Diagnostic.Create(ConstantNotConstantRule, location));
+ continue;
+ }
+
+ var rawValue = constantValue.Value;
+ if (!argConstantParameter.ValidateValue(argument, rawValue, out var valueDiagnostic))
+ {
+ context.ReportDiagnostic(valueDiagnostic);
+ }
+ }
+ }
+
+ protected abstract void RegisterAttributeSyntax(CompilationStartAnalysisContext context);
+
+ protected void OnParameterWithConstantExecptedAttribute(IParameterSymbol parameter, Action reportAction)
+ {
+ if (!ValidateConstantExpectedParameter(parameter, out ImmutableArray diagnostics))
+ {
+ foreach (var diagnostic in diagnostics)
+ {
+ reportAction(diagnostic);
+ }
+ }
+ }
+
+ private static bool TryCreateConstantExpectedParameter(IParameterSymbol parameterSymbol, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
+ {
+ if (!TryGetConstantExpectedAttributeData(parameterSymbol, out var attributeData))
+ {
+ parameter = null;
+ return false;
+ }
+
+ switch (parameterSymbol.Type.SpecialType)
+ {
+ case SpecialType.System_Char:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, char.MinValue, char.MaxValue, out parameter);
+ case SpecialType.System_Byte:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, byte.MinValue, byte.MaxValue, out parameter);
+ case SpecialType.System_UInt16:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, ushort.MinValue, ushort.MaxValue, out parameter);
+ case SpecialType.System_UInt32:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, out parameter);
+ case SpecialType.System_UInt64:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, ulong.MinValue, ulong.MaxValue, out parameter);
+ case SpecialType.System_UIntPtr:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, out parameter);
+ case SpecialType.System_SByte:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, sbyte.MinValue, sbyte.MaxValue, out parameter);
+ case SpecialType.System_Int16:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, short.MinValue, short.MaxValue, out parameter);
+ case SpecialType.System_Int32:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, out parameter);
+ case SpecialType.System_Int64:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, long.MinValue, long.MaxValue, out parameter);
+ case SpecialType.System_IntPtr:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, out parameter);
+ case SpecialType.System_Single:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, float.MinValue, float.MaxValue, out parameter);
+ case SpecialType.System_Double:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, double.MinValue, double.MaxValue, out parameter);
+ case SpecialType.System_Boolean:
+ return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, false, true, out parameter);
+ case SpecialType.System_String:
+ return StringConstantExpectedParameter.TryCreate(parameterSymbol, attributeData, out parameter);
+ default:
+ parameter = null;
+ return false;
+ }
+ }
+
+ private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol, out ImmutableArray diagnostics)
+ {
+ if (!TryGetConstantExpectedAttributeData(parameterSymbol, out var attributeData))
+ {
+ diagnostics = ImmutableArray.Empty;
+ return false;
+ }
+
+ switch (parameterSymbol.Type.SpecialType)
+ {
+ case SpecialType.System_Char:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, char.MinValue, char.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Byte:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, byte.MinValue, byte.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_UInt16:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, ushort.MinValue, ushort.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_UInt32:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_UInt64:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, ulong.MinValue, ulong.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_UIntPtr:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_SByte:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, sbyte.MinValue, sbyte.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Int16:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, short.MinValue, short.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Int32:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Int64:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, long.MinValue, long.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_IntPtr:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Single:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, float.MinValue, float.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Double:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, double.MinValue, double.MaxValue, Helper, out diagnostics);
+ case SpecialType.System_Boolean:
+ return UnmanagedHelper.Validate(parameterSymbol, attributeData, false, true, Helper, out diagnostics);
+ case SpecialType.System_String:
+ return StringConstantExpectedParameter.Validate(attributeData, out diagnostics);
+ case SpecialType.None when parameterSymbol.Type.TypeKind == TypeKind.TypeParameter:
+ return ValidateGenericConstantCase(attributeData, out diagnostics);
+ default:
+ diagnostics = Helper.ParameterIsInvalid(parameterSymbol.Type.ToDisplayString(), attributeData.ApplicationSyntaxReference.GetSyntax());
+ return false;
+ }
+ }
+ private bool ValidateGenericConstantCase(AttributeData attributeData, out ImmutableArray diagnostics)
+ {
+ var (min, max) = GetAttributeConstants(attributeData);
+ // Ensure min max is unassigned/null
+ if (min is not null || max is not null)
+ {
+ diagnostics = ImmutableArray.Create(
+ Diagnostic.Create(IncompatibleConstantForMinMaxRule,
+ attributeData.ApplicationSyntaxReference.GetSyntax().GetLocation(),
+ "generic"));
+ return false;
+ }
+ diagnostics = ImmutableArray.Empty;
+ return true;
+ }
+
+ private static bool TryGetConstantExpectedAttributeData(IParameterSymbol parameter, [NotNullWhen(true)] out AttributeData? attributeData)
+ {
+ AttributeData? constantExpectedAttributeData = parameter.GetAttributes()
+ .FirstOrDefault(attrData => IsConstantExpectedAttribute(attrData.AttributeClass));
+ attributeData = constantExpectedAttributeData;
+ return constantExpectedAttributeData is not null;
+ }
+
+ private static bool IsConstantExpectedAttribute(INamedTypeSymbol namedType)
+ {
+ if (!namedType.Name.Equals(ConstantExpectedAttribute, StringComparison.Ordinal))
+ {
+ return false;
+ }
+ if (!namedType.GetMembers().OfType().All(s => s.Name.Equals("Min", StringComparison.Ordinal) || s.Name.Equals("Max", StringComparison.Ordinal)))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private abstract class ConstantExpectedParameter
+ {
+ protected ConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax)
+ {
+ Parameter = parameter;
+ AttributeSyntax = attributeSyntax;
+ }
+
+ public IParameterSymbol Parameter { get; }
+ public SyntaxNode AttributeSyntax { get; }
+
+ public abstract bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics);
+ public abstract bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics);
+ }
+
+ private sealed class StringConstantExpectedParameter : ConstantExpectedParameter
+ {
+ public StringConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax) : base(parameter, attributeSyntax) { }
+
+ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ {
+ if (subsetCandidate is not StringConstantExpectedParameter)
+ {
+ validationDiagnostics = Diagnostic.Create(AttributeNotSameTypeRule, subsetCandidate.AttributeSyntax.GetLocation(), Parameter.Type.ToDisplayString());
+ return false;
+ }
+ validationDiagnostics = null;
+ return true;
+ }
+
+ public override bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ {
+ if (constant is not string and not null)
+ {
+ validationDiagnostics = argument.CreateDiagnostic(ConstantNotConstantRule);
+ return false;
+ }
+ validationDiagnostics = null;
+ return true;
+ }
+
+ public static bool TryCreate(IParameterSymbol parameterSymbol, AttributeData attributeData, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
+ {
+ if (!IsMinMaxValid(attributeData))
+ {
+ parameter = null;
+ return false;
+ }
+ parameter = new StringConstantExpectedParameter(parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax());
+ return true;
+ }
+
+ public static bool Validate(AttributeData attributeData, out ImmutableArray diagnostics)
+ {
+ if (!IsMinMaxValid(attributeData))
+ {
+ diagnostics = ImmutableArray.Create(Diagnostic.Create(IncompatibleConstantForMinMaxRule, attributeData.ApplicationSyntaxReference.GetSyntax().GetLocation(), "string"));
+ return false;
+ }
+ diagnostics = ImmutableArray.Empty;
+ return true;
+ }
+
+ private static bool IsMinMaxValid(AttributeData attributeData)
+ {
+ (object? min, object? max) = GetAttributeConstants(attributeData);
+
+ return min is null && max is null;
+ }
+ }
+
+ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(AttributeData attributeData)
+ {
+ object? minConstant = null;
+ object? maxConstant = null;
+
+ foreach (var namedArg in attributeData.NamedArguments)
+ {
+ if (namedArg.Key.Equals("Min", StringComparison.Ordinal))
+ {
+ minConstant = ToObject(namedArg.Value);
+ }
+ else if (namedArg.Key.Equals("Max", StringComparison.Ordinal))
+ {
+ maxConstant = ToObject(namedArg.Value);
+ }
+ }
+
+ return (minConstant, maxConstant);
+ static object? ToObject(TypedConstant typedConstant)
+ {
+ if (typedConstant.IsNull)
+ {
+ return null;
+ }
+ if (typedConstant.Kind == TypedConstantKind.Array)
+ {
+ return typedConstant.Values;
+ }
+ return typedConstant.Value;
+ }
+ }
+
+ protected abstract class DiagnosticHelper
+ {
+ public abstract Location? GetMinLocation(SyntaxNode attributeSyntax);
+ public abstract Location? GetMaxLocation(SyntaxNode attributeSyntax);
+
+ public ImmutableArray ParameterIsInvalid(string expectedTypeName, SyntaxNode attributeSyntax) => ImmutableArray.Create(Diagnostic.Create(InvalidTypeRule, attributeSyntax.GetLocation(), expectedTypeName));
+
+ public Diagnostic MinIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(IncompatibleConstantTypeRule, GetMinLocation(attributeSyntax)!, "Min", expectedTypeName);
+
+ public Diagnostic MaxIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(IncompatibleConstantTypeRule, GetMaxLocation(attributeSyntax)!, "Max", expectedTypeName);
+
+ public Diagnostic MinIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(InvalidBoundsRule, GetMinLocation(attributeSyntax)!, "Min", typeMinValue, typeMaxValue);
+
+ public Diagnostic MaxIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(InvalidBoundsRule, GetMaxLocation(attributeSyntax)!, "Max", typeMinValue, typeMaxValue);
+
+ public static Diagnostic MinMaxIsInverted(SyntaxNode attributeSyntax) => Diagnostic.Create(InvertedRangeRule, attributeSyntax.GetLocation());
+
+ public ImmutableArray GetError(ErrorKind errorFlags, IParameterSymbol parameterSymbol, SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue)
+ {
+ switch (errorFlags)
+ {
+ case ErrorKind.MinIsIncompatible:
+ return ImmutableArray.Create(MinIsIncompatible(parameterSymbol.Type.ToDisplayString(), attributeSyntax));
+ case ErrorKind.MaxIsIncompatible:
+ return ImmutableArray.Create(MaxIsIncompatible(parameterSymbol.Type.ToDisplayString(), attributeSyntax));
+ case ErrorKind.MinIsIncompatible | ErrorKind.MaxIsIncompatible:
+ var expectedTypeName = parameterSymbol.Type.ToDisplayString();
+ return ImmutableArray.Create(MinIsIncompatible(expectedTypeName, attributeSyntax), MaxIsIncompatible(expectedTypeName, attributeSyntax));
+ case ErrorKind.MinIsOutOfRange:
+ return ImmutableArray.Create(MinIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue));
+ case ErrorKind.MaxIsOutOfRange:
+ return ImmutableArray.Create(MaxIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue));
+ case ErrorKind.MinIsOutOfRange | ErrorKind.MaxIsOutOfRange:
+ return ImmutableArray.Create(MinIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue), MaxIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue));
+ case ErrorKind.MinIsOutOfRange | ErrorKind.MaxIsIncompatible:
+ return ImmutableArray.Create(MinIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue), MaxIsIncompatible(parameterSymbol.Type.ToDisplayString(), attributeSyntax));
+ case ErrorKind.MinIsIncompatible | ErrorKind.MaxIsOutOfRange:
+ return ImmutableArray.Create(MinIsIncompatible(parameterSymbol.Type.ToDisplayString(), attributeSyntax), MaxIsOutOfRange(attributeSyntax, typeMinValue, typeMaxValue));
+ case ErrorKind.MinMaxInverted:
+ return ImmutableArray.Create(MinMaxIsInverted(attributeSyntax));
+ default:
+ throw new ArgumentOutOfRangeException(nameof(errorFlags));
+ }
+ }
+ }
+
+ [Flags]
+ protected enum ErrorKind
+ {
+ None = 0,
+ ///
+ /// mutually exclusive with MinIsIncompatible and MinMaxInverted
+ ///
+ MinIsOutOfRange = 1,
+ ///
+ /// mutually exclusive with MinIsOutOfRange and MinMaxInverted
+ ///
+ MinIsIncompatible = 1 << 2,
+ ///
+ /// mutually exclusive with MaxIsIncompatible and MinMaxInverted
+ ///
+ MaxIsOutOfRange = 1 << 3,
+ ///
+ /// mutually exclusive with MaxIsOutOfRange and MinMaxInverted
+ ///
+ MaxIsIncompatible = 1 << 4,
+ ///
+ /// mutually exclusive
+ ///
+ MinMaxInverted = 1 << 5,
+ }
+ }
+}
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 dc80994265..cd2c79c8d4 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 2f687780a8..b6c01dc110 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 796bdc6015..7eb593ea59 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 251817ef26..ddde7f910b 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 32e5239392..4176ffd086 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 7009ff1c2d..ffd6c84599 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 00e6daa4b9..3aee1ca4ca 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 ac5808463f..b8e6d73bac 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 3bf860483d..77ea39409b 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 fcc7b39172..3daf0fc8a1 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 92c255c2f8..c8d7ff18b7 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 c1756ddba4..fdbab5f30f 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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 1fa0cbd50f..acccfcaee9 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,71 @@
, Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
+
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the paramter.
+
+
+
+ Incorerct use of ConstantExpectedAttribute
+ Incorerct use of ConstantExpectedAttribute
+
+
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
+
+
+
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The Min/Max condition can only be null for '{0}' types.
+ The Min/Max condition can only be null for '{0}' types.
+
+
+
+ The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' condition does not match parameter type of '{1}'.
+
+
+
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+
+
+
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotaed with ConstantExpected.
+
+
+
+ The Min and Max conditions are inverted.
+ The Min and Max conditions are inverted.
+
+
+
+ The argument should be a constant.
+ The argument should be a constant.
+
+
+
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+
+
+ The parameter expects a constant for best performance.
+ The parameter expects a constant for best performance.
+
+
+
+ Constant is expected for the parameter
+ Constant is expected for the parameter
+
+ 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/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
new file mode 100644
index 0000000000..9ff84053a9
--- /dev/null
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -0,0 +1,470 @@
+// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Microsoft.CodeAnalysis.Testing;
+using Microsoft.NetCore.Analyzers.Performance;
+using Xunit;
+using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
+ Microsoft.NetCore.CSharp.Analyzers.Performance.CSharpConstantExpectedAnalyzer,
+ Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
+
+namespace Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.Microsoft.NetCore.Analyzers.Performance
+{
+ public sealed class ConstantExpectedTests
+ {
+ [Fact]
+ public static async Task TestConstantExpectedSupportedTypesAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethodByte([ConstantExpected] byte val)
+ {
+ }
+ public static void TestMethodSByte([ConstantExpected] sbyte val)
+ {
+ }
+ public static void TestMethodUInt16([ConstantExpected] ushort val)
+ {
+ }
+ public static void TestMethodInt16([ConstantExpected] short val)
+ {
+ }
+ public static void TestMethodUInt32([ConstantExpected] uint val)
+ {
+ }
+ public static void TestMethodInt32([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethodUInt64([ConstantExpected] ulong val)
+ {
+ }
+ public static void TestMethodInt64([ConstantExpected] long val)
+ {
+ }
+ public static void TestMethodFloat([ConstantExpected] float val)
+ {
+ }
+ public static void TestMethodDouble([ConstantExpected] double val)
+ {
+ }
+ public static void TestMethodBoolean([ConstantExpected] bool val)
+ {
+ }
+ public static void TestMethodString([ConstantExpected] string val)
+ {
+ }
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+
+ public static class GenenricClass
+ {
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+ }
+}
+";
+ await TestCSAsync(csInput);
+ }
+
+ [Fact]
+ public static async Task TestConstantExpectedUnsupportedTypesAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethodObject([{|#0:ConstantExpected|}] object val)
+ {
+ }
+ public static void TestMethodCustomClass([{|#1:ConstantExpected|}] Test val)
+ {
+ }
+ public static void TestMethodDecimal([{|#2:ConstantExpected|}] decimal val)
+ {
+ }
+ public static void TestMethodByteArray([{|#3:ConstantExpected|}] byte[] val)
+ {
+ }
+ public static void TestMethodGenericArray([{|#4:ConstantExpected|}] T[] val)
+ {
+ }
+ public static void TestMethodValueTuple([{|#5:ConstantExpected|}] ValueTuple val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(0)
+ .WithArguments("object"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(1)
+ .WithArguments("Test"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(2)
+ .WithArguments("decimal"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(3)
+ .WithArguments("byte[]"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(4)
+ .WithArguments("T[]"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ .WithLocation(5)
+ .WithArguments("(int, long)"));
+ }
+
+ [Fact]
+ public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod([ConstantExpected({|#0:Min = ""min""|})] int val)
+ {
+ }
+ public static void TestMethod2([ConstantExpected({|#1:Min = ""min""|}, {|#2:Max = ""a""|})] int val)
+ {
+ }
+ public static void TestMethod3([ConstantExpected({|#3:Max = true|})] short val)
+ {
+ }
+ public static void TestMethodString([{|#4:ConstantExpected(Max = true)|}] string val)
+ {
+ }
+ public static void TestMethodGeneric([{|#5:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
+ {
+ }
+
+ public static class GenenricClass
+ {
+ public static void TestMethodGeneric([{|#6:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
+ {
+ }
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(0)
+ .WithArguments("Min", "int"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(1)
+ .WithArguments("Min", "int"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(2)
+ .WithArguments("Max", "int"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(3)
+ .WithArguments("Max", "short"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(4)
+ .WithArguments("string"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(5)
+ .WithArguments("generic"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(6)
+ .WithArguments("generic"));
+ }
+
+ [Fact]
+ public static async Task TestConstantExpectedInvalidTypeRangeValueAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod([ConstantExpected({|#0:Min = 256|})] byte val)
+ {
+ }
+ public static void TestMethod2([ConstantExpected({|#1:Min = -256|}, {|#2:Max = 256|})] byte val)
+ {
+ }
+ public static void TestMethod3([ConstantExpected({|#3:Min = double.MinValue|}, {|#4:Max = double.MaxValue|})] float val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(0)
+ .WithArguments("Min", "0", "255"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(1)
+ .WithArguments("Min", "0", "255"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(2)
+ .WithArguments("Max", "0", "255"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(3)
+ .WithArguments("Min", "-3.4028235E+38", "3.4028235E+38"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(4)
+ .WithArguments("Max", "-3.4028235E+38", "3.4028235E+38"));
+ }
+
+ [Fact]
+ public static async Task TestArgumentConstantAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod()
+ {
+ TestMethodWithConstant(10);
+ TestMethodWithConstrainedConstant(10);
+ TestMethodWithConstrainedConstant(2*5);
+ TestMethodGeneric(10);
+ GenenricClass.TestMethodGeneric(10);
+ }
+ public static void TestMethodWithConstant([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
+ {
+ }
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+
+ public static class GenenricClass
+ {
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+ }
+}
+";
+ await TestCSAsync(csInput);
+ }
+
+ [Fact]
+ public static async Task TestArgumentNotConstantAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod(int nonConstant)
+ {
+ TestMethodWithConstant({|#0:nonConstant|});
+ TestMethodGeneric({|#1:nonConstant|});
+ GenenricClass.TestMethodGeneric({|#2:nonConstant|});
+ }
+ public static void TestMethodWithConstant([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+
+ public static class GenenricClass
+ {
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(0),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(1),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(2));
+ }
+
+ [Fact]
+ public static async Task TestArgumentOutOfRangeConstantAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod()
+ {
+ TestMethodWithConstant({|#0:11|});
+ }
+ public static void TestMethodWithConstant([ConstantExpected(Min=0, Max=10)] int val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantOutOfBoundsRule)
+ .WithLocation(0)
+ .WithArguments("0", "10"));
+ }
+
+ [Fact]
+ public static async Task TestArgumentInvalidGenericTypeParamterConstantAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod(int[] nonConstant)
+ {
+ TestMethodGeneric(nonConstant); // ignore scenario
+ GenenricClass.TestMethodGeneric(nonConstant); // ignore scenario
+ }
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+
+ public static class GenenricClass
+ {
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {
+ }
+ }
+}
+";
+ await TestCSAsync(csInput);
+ }
+
+
+ [Fact]
+ public static async Task TestConstantCompositionAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod([ConstantExpected] int constant)
+ {
+ TestMethodWithConstant(constant);
+ }
+ public static void TestMethodWithConstant([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethod2([ConstantExpected(Min = 10, Max = 20)] int constant)
+ {
+ TestMethodWithConstant(constant);
+ TestMethod2WithConstrainedConstant(constant);
+ }
+ public static void TestMethod2WithConstant([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput);
+ }
+
+ [Fact]
+ public static async Task TestConstantCompositionOutOfRangeAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod([{|#0:ConstantExpected|}] long constant)
+ {
+ TestMethodWithConstant((int)constant);
+ }
+ public static void TestMethod([{|#1:ConstantExpected|}] short constant)
+ {
+ TestMethodWithConstant(constant);
+ }
+ public static void TestMethodWithConstant([ConstantExpected] int val)
+ {
+ }
+ public static void TestMethod2([{|#2:ConstantExpected(Min = 10, Max = 21)|}] int constant)
+ {
+ TestMethod2WithConstrainedConstant(constant);
+ }
+ public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeNotSameTypeRule)
+ .WithLocation(0)
+ .WithArguments("int"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeNotSameTypeRule)
+ .WithLocation(1)
+ .WithArguments("int"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeOutOfBoundsRule)
+ .WithLocation(2)
+ .WithArguments("10", "20"));
+ }
+
+
+ private static async Task TestCSAsync(string source, params DiagnosticResult[] diagnosticResults)
+ {
+ var test = new VerifyCS.Test
+ {
+ TestCode = source,
+ LanguageVersion = CSharp.LanguageVersion.Preview,
+ };
+ // TODO: remove when the type is avaiable
+ test.TestState.Sources.Add(s_attributeSource);
+ test.ExpectedDiagnostics.AddRange(diagnosticResults);
+ await test.RunAsync();
+ }
+
+ private static readonly string s_attributeSource = @"#nullable enable
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
+ public sealed class ConstantExpectedAttribute : Attribute
+ {
+ public object? Min { get; set; }
+ public object? Max { get; set; }
+ }
+}";
+
+ }
+}
From f39fc6041da1f248645c459c824453f0ae64c684 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:20:47 +0800
Subject: [PATCH 02/27] Fix floating point string culture issue
---
.../Performance/ConstantExpectedTests.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index 9ff84053a9..5302af7af3 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -219,10 +219,10 @@ await TestCSAsync(csInput,
.WithArguments("Max", "0", "255"),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(3)
- .WithArguments("Min", "-3.4028235E+38", "3.4028235E+38"),
+ .WithArguments("Min", float.MinValue.ToString(), float.MaxValue.ToString()),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(4)
- .WithArguments("Max", "-3.4028235E+38", "3.4028235E+38"));
+ .WithArguments("Max", float.MinValue.ToString(), float.MaxValue.ToString()));
}
[Fact]
From 74d95332e6b55a68a7d4c8e486b2b68820f6f09c Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:20:47 +0800
Subject: [PATCH 03/27] Update tests fix some typo
---
.../CSharpConstantExpectedAnalyzer.cs | 2 +-
...onstantExpectedAnalyzer.UnmanagedHelper.cs | 102 ++--
.../Performance/ConstantExpectedAnalyzer.cs | 21 +-
.../Performance/ConstantExpectedTests.cs | 476 ++++++++++++++----
4 files changed, 433 insertions(+), 168 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 1698498f50..15341b0fc8 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -33,7 +33,7 @@ private void OnAttributeNode(SyntaxNodeAnalysisContext context)
var parameter = (ParameterSyntax)attributeSyntax.Parent.Parent;
var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter);
- OnParameterWithConstantExecptedAttribute(parameterSymbol, context.ReportDiagnostic);
+ OnParameterWithConstantExpectedAttribute(parameterSymbol, context.ReportDiagnostic);
}
private sealed class CSharpDiagnosticHelper : DiagnosticHelper
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
index 8236b6b66e..053763ed38 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
@@ -14,40 +14,40 @@ public abstract partial class ConstantExpectedAnalyzer
{
private sealed class UnmanagedHelper where T : unmanaged
{
- private static readonly UnmanagedHelper.ConstantExpectedParameterFactory? _instance;
- private static UnmanagedHelper.ConstantExpectedParameterFactory Instance => _instance ?? throw new InvalidOperationException("unsupported type");
+ private static readonly ConstantExpectedParameterFactory? _instance;
+ private static ConstantExpectedParameterFactory Instance => _instance ?? throw new InvalidOperationException("unsupported type");
static UnmanagedHelper()
{
if (typeof(T) == typeof(long))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertInt64, TryTransformInt64);
- _instance = new UnmanagedHelper.ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(ulong))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertUInt64, TryTransformUInt64);
- _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(float))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertSingle, TryTransformSingle);
- _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(double))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertDouble, TryTransformDouble);
- _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(char))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertChar, TryTransformChar);
- _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(bool))
{
var helper = new UnmanagedHelper.TransformHelper(TryConvertBoolean, TryTransformBoolean);
- _instance = new ConstantExpectedParameterFactory((UnmanagedHelper.TransformHelper)(object)helper);
+ _instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
}
@@ -264,51 +264,50 @@ private static bool TryConvertUnsignedInteger(object constant, out ulong integer
private static bool TryConvertInt64(object? constant, out long value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = Convert.ToInt64(constant);
+ return true;
}
- value = Convert.ToInt64(constant);
- return true;
+ value = default;
+ return false;
}
private static bool TryTransformInt64(object constant, out long value, out bool isInvalid)
{
bool isValidSigned = TryConvertSignedInteger(constant, out value);
isInvalid = false;
- if (!isValidSigned)
+ if (isValidSigned)
{
- bool isValidUnsigned = TryConvertUnsignedInteger(constant, out _);
- if (!isValidUnsigned)
- {
- isInvalid = true;
- }
+ return isValidSigned;
+ }
+ if (!TryConvertUnsignedInteger(constant, out _))
+ {
+ isInvalid = true;
}
-
return isValidSigned;
}
private static bool TryConvertUInt64(object? constant, out ulong value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = Convert.ToUInt64(constant);
+ return true;
}
- value = Convert.ToUInt64(constant);
- return true;
+ value = default;
+ return false;
}
private static bool TryTransformUInt64(object constant, out ulong value, out bool isInvalid)
{
bool isValidUnsigned = TryConvertUnsignedInteger(constant, out value);
isInvalid = false;
- if (!isValidUnsigned)
+ if (isValidUnsigned)
{
- bool isValidSigned = TryConvertSignedInteger(constant, out _);
- if (!isValidSigned)
- {
- isInvalid = true;
- }
+ return isValidUnsigned;
+ }
+ if (!TryConvertSignedInteger(constant, out _))
+ {
+ isInvalid = true;
}
return isValidUnsigned;
}
@@ -336,13 +335,13 @@ private static bool TryTransformChar(object constant, out char value, out bool i
}
private static bool TryConvertChar(object? constant, out char value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = Convert.ToChar(constant);
+ return true;
}
- value = Convert.ToChar(constant);
- return true;
+ value = default;
+ return false;
}
private static bool TryTransformBoolean(object constant, out bool value, out bool isInvalid)
@@ -359,13 +358,13 @@ private static bool TryTransformBoolean(object constant, out bool value, out boo
}
private static bool TryConvertBoolean(object? constant, out bool value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = (bool)constant;
+ return true;
}
- value = (bool)constant;
- return true;
+ value = default;
+ return false;
}
private static bool TryTransformSingle(object constant, out float value, out bool isInvalid)
@@ -389,15 +388,16 @@ private static bool TryTransformSingle(object constant, out float value, out boo
isInvalid = false;
return true;
}
+
private static bool TryConvertSingle(object? constant, out float value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = Convert.ToSingle(constant);
+ return true;
}
- value = Convert.ToSingle(constant);
- return true;
+ value = default;
+ return false;
}
private static bool TryTransformDouble(object constant, out double value, out bool isInvalid)
@@ -423,13 +423,13 @@ private static bool TryTransformDouble(object constant, out double value, out bo
}
private static bool TryConvertDouble(object? constant, out double value)
{
- if (constant is null)
+ if (constant is not null)
{
- value = default;
- return false;
+ value = Convert.ToDouble(constant);
+ return true;
}
- value = Convert.ToDouble(constant);
- return true;
+ value = default;
+ return false;
}
}
}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index 3007649524..7f6b5b15f4 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -171,7 +171,7 @@ private static void OnInvocation(OperationAnalysisContext context)
protected abstract void RegisterAttributeSyntax(CompilationStartAnalysisContext context);
- protected void OnParameterWithConstantExecptedAttribute(IParameterSymbol parameter, Action reportAction)
+ protected void OnParameterWithConstantExpectedAttribute(IParameterSymbol parameter, Action reportAction)
{
if (!ValidateConstantExpectedParameter(parameter, out ImmutableArray diagnostics))
{
@@ -301,15 +301,10 @@ private static bool TryGetConstantExpectedAttributeData(IParameterSymbol paramet
private static bool IsConstantExpectedAttribute(INamedTypeSymbol namedType)
{
- if (!namedType.Name.Equals(ConstantExpectedAttribute, StringComparison.Ordinal))
- {
- return false;
- }
- if (!namedType.GetMembers().OfType().All(s => s.Name.Equals("Min", StringComparison.Ordinal) || s.Name.Equals("Max", StringComparison.Ordinal)))
- {
- return false;
- }
- return true;
+ return namedType.Name.Equals(ConstantExpectedAttribute, StringComparison.Ordinal) &&
+ namedType.GetMembers().OfType()
+ .All(s => s.Name.Equals("Min", StringComparison.Ordinal) ||
+ s.Name.Equals("Max", StringComparison.Ordinal));
}
private abstract class ConstantExpectedParameter
@@ -407,11 +402,7 @@ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(A
{
return null;
}
- if (typedConstant.Kind == TypedConstantKind.Array)
- {
- return typedConstant.Values;
- }
- return typedConstant.Value;
+ return typedConstant.Kind == TypedConstantKind.Array ? typedConstant.Values : typedConstant.Value;
}
}
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index 5302af7af3..d79d073620 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -12,8 +12,58 @@ namespace Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.Microsoft.NetCore.Analyz
{
public sealed class ConstantExpectedTests
{
+ [Theory]
+ [InlineData("char", "char.MinValue", "char.MaxValue")]
+ [InlineData("byte", "byte.MinValue", "byte.MaxValue")]
+ [InlineData("ushort", "ushort.MinValue", "ushort.MaxValue")]
+ [InlineData("uint", "uint.MinValue", "uint.MaxValue")]
+ [InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
+ [InlineData("nuint", "uint.MinValue", "uint.MaxValue")]
+ [InlineData("sbyte", "sbyte.MinValue", "sbyte.MaxValue")]
+ [InlineData("short", "short.MinValue", "short.MaxValue")]
+ [InlineData("int", "int.MinValue", "int.MaxValue")]
+ [InlineData("long", "long.MinValue", "long.MaxValue")]
+ [InlineData("nint", "int.MinValue", "int.MaxValue")]
+ [InlineData("float", "float.MinValue", "float.MaxValue")]
+ [InlineData("double", "double.MinValue", "double.MaxValue")]
+ public static async Task TestConstantExpectedSupportedUnmanagedTypesAsync(string type, string minValue, string maxValue)
+ {
+
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod1([ConstantExpected] {type} val)
+ {{
+ }}
+ public static void TestMethod2([ConstantExpected(Min={minValue})] {type} val)
+ {{
+ }}
+ public static void TestMethod3([ConstantExpected(Max={maxValue})] {type} val)
+ {{
+ }}
+ public static void TestMethod4([ConstantExpected(Min={minValue}, Max={maxValue})] {type} val)
+ {{
+ }}
+ public static void TestMethod5([ConstantExpected(Min=null)] {type} val)
+ {{
+ }}
+ public static void TestMethod6([ConstantExpected(Max=null)] {type} val)
+ {{
+ }}
+ public static void TestMethod7([ConstantExpected(Min=null, Max=null)] {type} val)
+ {{
+ }}
+}}
+";
+ await TestCSAsync(csInput);
+ }
+
[Fact]
- public static async Task TestConstantExpectedSupportedTypesAsync()
+ public static async Task TestConstantExpectedSupportedComplexTypesAsync()
{
string csInput = @"
@@ -23,39 +73,6 @@ public static async Task TestConstantExpectedSupportedTypesAsync()
public class Test
{
- public static void TestMethodByte([ConstantExpected] byte val)
- {
- }
- public static void TestMethodSByte([ConstantExpected] sbyte val)
- {
- }
- public static void TestMethodUInt16([ConstantExpected] ushort val)
- {
- }
- public static void TestMethodInt16([ConstantExpected] short val)
- {
- }
- public static void TestMethodUInt32([ConstantExpected] uint val)
- {
- }
- public static void TestMethodInt32([ConstantExpected] int val)
- {
- }
- public static void TestMethodUInt64([ConstantExpected] ulong val)
- {
- }
- public static void TestMethodInt64([ConstantExpected] long val)
- {
- }
- public static void TestMethodFloat([ConstantExpected] float val)
- {
- }
- public static void TestMethodDouble([ConstantExpected] double val)
- {
- }
- public static void TestMethodBoolean([ConstantExpected] bool val)
- {
- }
public static void TestMethodString([ConstantExpected] string val)
{
}
@@ -126,10 +143,92 @@ await TestCSAsync(csInput,
.WithArguments("(int, long)"));
}
- [Fact]
- public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync()
+ [Theory]
+ [InlineData("char", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("sbyte", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("short", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("int", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("long", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("nint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("byte", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("ushort", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("uint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("ulong", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("nuint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("bool", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("float", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ [InlineData("double", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
+ public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync(string type, string min1, string min2, string max2, string max3)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod2([ConstantExpected({{|#1:Min = {min2}|}}, {{|#2:Max = {max2}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod3([ConstantExpected({{|#3:Max = {max3}|}})] {type} val)
+ {{
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(0)
+ .WithArguments("Min", type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(1)
+ .WithArguments("Min", type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(2)
+ .WithArguments("Max", type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(3)
+ .WithArguments("Max", type));
+ }
+
+ [Theory]
+ [InlineData("char", "'Z'", "'A'")]
+ [InlineData("sbyte", "1", "0")]
+ [InlineData("short", "1", "0")]
+ [InlineData("int", "1", "0")]
+ [InlineData("long", "1", "0")]
+ [InlineData("nint", "1", "0")]
+ [InlineData("byte", "1", "0")]
+ [InlineData("ushort", "1", "0")]
+ [InlineData("uint", "1", "0")]
+ [InlineData("ulong", "1", "0")]
+ [InlineData("nuint", "1", "0")]
+ [InlineData("float", "1", "0")]
+ [InlineData("double", "1", "0")]
+ public static async Task TestConstantExpectedInvertedConstantTypeErrorAsync(string type, string min, string max)
{
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod([{{|#0:ConstantExpected(Min = {min}, Max = {max})|}}] {type} val)
+ {{
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvertedRangeRule)
+ .WithLocation(0));
+ }
+ [Fact]
+ public static async Task TestConstantExpectedIncompatibleConstantMinMaxTypeErrorAsync()
+ {
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -137,96 +236,250 @@ public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync(
public class Test
{
- public static void TestMethod([ConstantExpected({|#0:Min = ""min""|})] int val)
+ public static void TestMethodString1([{|#0:ConstantExpected(Min = true)|}] string val)
{
}
- public static void TestMethod2([ConstantExpected({|#1:Min = ""min""|}, {|#2:Max = ""a""|})] int val)
+ public static void TestMethodString2([{|#1:ConstantExpected(Min = true, Max = 5f)|}] string val)
{
}
- public static void TestMethod3([ConstantExpected({|#3:Max = true|})] short val)
+ public static void TestMethodString3([{|#2:ConstantExpected(Max = 10.0)|}] string val)
{
}
- public static void TestMethodString([{|#4:ConstantExpected(Max = true)|}] string val)
+
+ public static void TestMethodGeneric1([{|#3:ConstantExpected(Min = ""min"")|}] T val)
{
- }
- public static void TestMethodGeneric([{|#5:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
+ }
+ public static void TestMethodGeneric2([{|#4:ConstantExpected(Min = ""min"", Max = '1')|}] T val)
{
- }
-
+ }
+ public static void TestMethodGeneric3([{|#5:ConstantExpected(Max = ulong.MaxValue)|}] T val)
+ {
+ }
public static class GenenricClass
{
- public static void TestMethodGeneric([{|#6:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
+ public static void TestMethodGeneric1([{|#6:ConstantExpected(Min = ""min"")|}] T val)
+ {
+ }
+ public static void TestMethodGeneric2([{|#7:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
+ {
+ }
+ public static void TestMethodGeneric3([{|#8:ConstantExpected(Max = ""a"")|}] T val)
{
}
}
}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(0)
- .WithArguments("Min", "int"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithArguments("string"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(1)
- .WithArguments("Min", "int"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithArguments("string"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(2)
- .WithArguments("Max", "int"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithArguments("string"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(3)
- .WithArguments("Max", "short"),
+ .WithArguments("generic"),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(4)
- .WithArguments("string"),
+ .WithArguments("generic"),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(5)
.WithArguments("generic"),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
.WithLocation(6)
+ .WithArguments("generic"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(7)
+ .WithArguments("generic"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(8)
.WithArguments("generic"));
}
[Fact]
- public static async Task TestConstantExpectedInvalidTypeRangeValueAsync()
+ public static async Task TestConstantExpectedInvalidBoundsAsync()
{
+ string[][] setArray = {
+ new[]
+ {
+ "byte", byte.MinValue.ToString(), byte.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "ushort", ushort.MinValue.ToString(), ushort.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "uint", uint.MinValue.ToString(), uint.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "ulong", ulong.MinValue.ToString(), ulong.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "-1", "-1"
+ },
+ new[]
+ {
+ "nuint", uint.MinValue.ToString(), uint.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "sbyte", sbyte.MinValue.ToString(), sbyte.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "short", short.MinValue.ToString(), short.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "int", int.MinValue.ToString(), int.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "long", long.MinValue.ToString(), long.MaxValue.ToString(),
+ "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue"
+ },
+ new[]
+ {
+ "nint", int.MinValue.ToString(), int.MaxValue.ToString(),
+ "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
+ },
+ new[]
+ {
+ "float", float.MinValue.ToString(), float.MaxValue.ToString(),
+ "double.MinValue", "double.MinValue", "double.MaxValue", "double.MaxValue"
+ }
+ };
- string csInput = @"
+ foreach (string[] set in setArray)
+ {
+ await TestTheoryAsync(set[0], set[1], set[2], set[3], set[4], set[5], set[6]);
+ }
+
+ static async Task TestTheoryAsync(string type, string min, string max, string min1, string min2, string max2,
+ string max3)
+ {
+ string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
public class Test
-{
- public static void TestMethod([ConstantExpected({|#0:Min = 256|})] byte val)
- {
- }
- public static void TestMethod2([ConstantExpected({|#1:Min = -256|}, {|#2:Max = 256|})] byte val)
- {
- }
- public static void TestMethod3([ConstantExpected({|#3:Min = double.MinValue|}, {|#4:Max = double.MaxValue|})] float val)
- {
- }
-}
+{{
+ public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod2([ConstantExpected({{|#1:Min = {min2}|}}, {{|#2:Max = {max2}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod3([ConstantExpected({{|#3:Max = {max3}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod4([ConstantExpected({{|#4:Min = false|}}, {{|#5:Max = {max2}|}})] {type} val)
+ {{
+ }}
+ public static void TestMethod5([ConstantExpected({{|#6:Min = {min2}|}}, {{|#7:Max = true|}})] {type} val)
+ {{
+ }}
+}}
";
- await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(0)
- .WithArguments("Min", "0", "255"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithArguments("Min", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(1)
- .WithArguments("Min", "0", "255"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithArguments("Min", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(2)
- .WithArguments("Max", "0", "255"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithArguments("Max", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
.WithLocation(3)
- .WithArguments("Min", float.MinValue.ToString(), float.MaxValue.ToString()),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithArguments("Max", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
.WithLocation(4)
- .WithArguments("Max", float.MinValue.ToString(), float.MaxValue.ToString()));
+ .WithArguments("Min", type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(5)
+ .WithArguments("Max", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(6)
+ .WithArguments("Min", min, max),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(7)
+ .WithArguments("Max", type));
+ }
+ }
+
+ [Theory]
+ [InlineData("char", "'A'", "'Z'", "'A'", "(char)('A'+'\\u0001')")]
+ [InlineData("byte", "10", "20", "10", "2*5")]
+ [InlineData("ushort", "10", "20", "10", "2*5")]
+ [InlineData("uint", "10", "20", "10", "2*5")]
+ [InlineData("ulong", "10", "20", "10", "2*5")]
+ [InlineData("nuint", "10", "20", "10", "2*5")]
+ [InlineData("sbyte", "10", "20", "10", "2*5")]
+ [InlineData("short", "10", "20", "10", "2*5")]
+ [InlineData("int", "10", "20", "10", "2*5")]
+ [InlineData("long", "10", "20", "10", "2*5")]
+ [InlineData("nint", "10", "20", "10", "2*5")]
+ [InlineData("float", "10", "20", "10", "2*5")]
+ [InlineData("double", "10", "20", "10", "2*5")]
+ [InlineData("bool", "true", "true", "true", "!false")]
+ [InlineData("string", "null", "null", "\"true\"", "\"false\"")]
+ public static async Task TestArgumentConstantAsync(string type, string minValue, string maxValue, string value, string expression)
+ {
+
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod()
+ {{
+ TestMethodWithConstant({value});
+ TestMethodWithConstant({expression});
+ TestMethodWithConstrainedConstant({value});
+ TestMethodWithConstrainedConstant({expression});
+ TestMethodGeneric<{type}>({value});
+ TestMethodGeneric<{type}>({expression});
+ GenericClass<{type}>.TestMethodGeneric({value});
+ GenericClass<{type}>.TestMethodGeneric({expression});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val)
+ {{
+ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {minValue}, Max = {maxValue})] {type} val)
+ {{
+ }}
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {{
+ }}
+
+ public static class GenericClass
+ {{
+ public static void TestMethodGeneric([ConstantExpected] T val)
+ {{
+ }}
+ }}
+}}
+";
+ await TestCSAsync(csInput);
}
[Fact]
- public static async Task TestArgumentConstantAsync()
+ public static async Task TestArgumentNotConstantAsync()
{
string csInput = @"
@@ -236,20 +489,15 @@ public static async Task TestArgumentConstantAsync()
public class Test
{
- public static void TestMethod()
+ public static void TestMethod(int nonConstant)
{
- TestMethodWithConstant(10);
- TestMethodWithConstrainedConstant(10);
- TestMethodWithConstrainedConstant(2*5);
- TestMethodGeneric(10);
- GenenricClass.TestMethodGeneric(10);
+ TestMethodWithConstant({|#0:nonConstant|});
+ TestMethodGeneric({|#1:nonConstant|});
+ GenenricClass.TestMethodGeneric({|#2:nonConstant|});
}
public static void TestMethodWithConstant([ConstantExpected] int val)
{
}
- public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
- {
- }
public static void TestMethodGeneric([ConstantExpected] T val)
{
}
@@ -262,11 +510,17 @@ public static void TestMethodGeneric([ConstantExpected] T val)
}
}
";
- await TestCSAsync(csInput);
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(0),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(1),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ .WithLocation(2));
}
[Fact]
- public static async Task TestArgumentNotConstantAsync()
+ public static async Task TestArgumentStringNotConstantAsync()
{
string csInput = @"
@@ -276,13 +530,13 @@ public static async Task TestArgumentNotConstantAsync()
public class Test
{
- public static void TestMethod(int nonConstant)
+ public static void TestMethod(string nonConstant)
{
TestMethodWithConstant({|#0:nonConstant|});
- TestMethodGeneric({|#1:nonConstant|});
- GenenricClass.TestMethodGeneric({|#2:nonConstant|});
+ TestMethodGeneric({|#1:nonConstant|});
+ GenenricClass.TestMethodGeneric({|#2:nonConstant|});
}
- public static void TestMethodWithConstant([ConstantExpected] int val)
+ public static void TestMethodWithConstant([ConstantExpected] string val)
{
}
public static void TestMethodGeneric([ConstantExpected] T val)
@@ -299,11 +553,11 @@ public static void TestMethodGeneric([ConstantExpected] T val)
";
await TestCSAsync(csInput,
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(0),
+ .WithLocation(0),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(1),
+ .WithLocation(1),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(2));
+ .WithLocation(2));
}
[Fact]
@@ -333,7 +587,7 @@ await TestCSAsync(csInput,
}
[Fact]
- public static async Task TestArgumentInvalidGenericTypeParamterConstantAsync()
+ public static async Task TestArgumentInvalidGenericTypeParameterConstantAsync()
{
string csInput = @"
@@ -363,7 +617,6 @@ public static void TestMethodGeneric([ConstantExpected] T val)
await TestCSAsync(csInput);
}
-
[Fact]
public static async Task TestConstantCompositionAsync()
{
@@ -398,6 +651,29 @@ public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10
await TestCSAsync(csInput);
}
+ [Fact]
+ public static async Task TestConstantCompositionStringAsync()
+ {
+
+ string csInput = @"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{
+ public static void TestMethod([ConstantExpected] string constant)
+ {
+ TestMethodWithConstant(constant);
+ }
+ public static void TestMethodWithConstant([ConstantExpected] string val)
+ {
+ }
+}
+";
+ await TestCSAsync(csInput);
+ }
+
[Fact]
public static async Task TestConstantCompositionOutOfRangeAsync()
{
@@ -441,7 +717,6 @@ await TestCSAsync(csInput,
.WithArguments("10", "20"));
}
-
private static async Task TestCSAsync(string source, params DiagnosticResult[] diagnosticResults)
{
var test = new VerifyCS.Test
@@ -465,6 +740,5 @@ public sealed class ConstantExpectedAttribute : Attribute
public object? Max { get; set; }
}
}";
-
}
}
From d13a77e5fae0eab4e808091627abfa9ffb0e5ecb Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:20:47 +0800
Subject: [PATCH 04/27] Fix typos
---
.../MicrosoftNetCoreAnalyzersResources.resx | 4 ++--
.../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 8 ++++----
.../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 8 ++++----
14 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index 8b025eec2b..a3b236142b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1835,7 +1835,7 @@
'{0}' uses the preview type '{1}' and needs to opt into preview features. See {2} for more information.
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttributeConstantExpectedAttribute is not applied correctly on the paramter.
@@ -1847,7 +1847,7 @@
The parameter expects a constant for best performance.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.The '{0}' condition does not match parameter type of '{1}'.
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 cd2c79c8d4..060689e670 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 b6c01dc110..f9d8997d06 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 7eb593ea59..7f8fa51d45 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 ddde7f910b..81795168d7 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 4176ffd086..df447b6f14 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 ffd6c84599..d8f123e9e8 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 3aee1ca4ca..25b9dc80ce 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 b8e6d73bac..0533bbe0bd 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 77ea39409b..0cf97189d6 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 3daf0fc8a1..c44cb66640 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 c8d7ff18b7..987b5d3684 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 fdbab5f30f..149ace6158 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
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 acccfcaee9..4345ad380a 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 @@
- Incorerct use of ConstantExpectedAttribute
- Incorerct use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
+ Incorrect use of ConstantExpectedAttribute
@@ -218,8 +218,8 @@
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
- The '{0}' parameter cannot have be annotaed with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
+ The '{0}' parameter cannot have be annotated with ConstantExpected.
From 8b3d43e8c76319a60d76a62b5a6bc94456880282 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:20:47 +0800
Subject: [PATCH 05/27] Rework test cases
Add new warning for missing attribute from interface or base class
---
.../CSharpConstantExpectedAnalyzer.cs | 1 -
.../MicrosoftNetCoreAnalyzersResources.resx | 3 +
.../Performance/ConstantExpectedAnalyzer.cs | 103 ++-
.../MicrosoftNetCoreAnalyzersResources.cs.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.de.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.es.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.fr.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.it.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.ja.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.ko.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.pl.xlf | 5 +
...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.ru.xlf | 5 +
.../MicrosoftNetCoreAnalyzersResources.tr.xlf | 5 +
...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 5 +
...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 5 +
.../Performance/ConstantExpectedTests.cs | 676 +++++++++---------
17 files changed, 525 insertions(+), 323 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 15341b0fc8..5ae0754cef 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -25,7 +25,6 @@ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext
private void OnAttributeNode(SyntaxNodeAnalysisContext context)
{
var attributeSyntax = (AttributeSyntax)context.Node;
- var sm = context.SemanticModel;
if (!attributeSyntax.Name.IsEquivalentTo(_constantExpectedIdentifier) && !attributeSyntax.Name.IsEquivalentTo(_constantExpectedAttributeIdentifier))
{
return;
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index a3b236142b..30cdfd6547 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1870,6 +1870,9 @@
The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index 7f6b5b15f4..a828714f6f 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -104,6 +104,16 @@ public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
isPortedFxCopRule: false,
isDataflowRule: false);
+ internal static readonly DiagnosticDescriptor AttributeExpectedRule = DiagnosticDescriptorHelper.Create(
+ CA1861,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedAttributExpectedMessage)),
+ DiagnosticCategory.Performance,
+ RuleLevel.BuildWarning,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
internal static readonly DiagnosticDescriptor AttributeNotSameTypeRule = DiagnosticDescriptorHelper.Create(
CA1861,
s_localizableUsageTitle,
@@ -115,7 +125,7 @@ public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
isDataflowRule: false);
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(
InvalidTypeRule, IncompatibleConstantTypeRule, IncompatibleConstantForMinMaxRule, InvalidBoundsRule, InvertedRangeRule,
- ConstantOutOfBoundsRule, ConstantNotConstantRule, AttributeOutOfBoundsRule, AttributeNotSameTypeRule);
+ ConstantOutOfBoundsRule, ConstantNotConstantRule, AttributeOutOfBoundsRule, AttributeExpectedRule, AttributeNotSameTypeRule);
protected abstract DiagnosticHelper Helper { get; }
@@ -129,9 +139,40 @@ public override void Initialize(AnalysisContext context)
private void OnCompilationStart(CompilationStartAnalysisContext context)
{
context.RegisterOperationAction(OnInvocation, OperationKind.Invocation);
+ context.RegisterSymbolAction(context => OnMethodSymbol(context), SymbolKind.Method);
RegisterAttributeSyntax(context);
return;
}
+ private static void OnMethodSymbol(SymbolAnalysisContext context)
+ {
+ var methodSymbol = (IMethodSymbol)context.Symbol;
+ if (TryGetMethodInterface(methodSymbol, out var interfaceMethodSymbol))
+ {
+ CheckAttribute(context, methodSymbol.Parameters, interfaceMethodSymbol.Parameters);
+ }
+ else if (methodSymbol.OverriddenMethod is not null)
+ {
+ CheckAttribute(context, methodSymbol.Parameters, methodSymbol.OverriddenMethod.Parameters);
+ }
+
+ static void CheckAttribute(SymbolAnalysisContext context, ImmutableArray parameters, ImmutableArray baseParameters)
+ {
+ for (var i = 0; i < parameters.Length; i++)
+ {
+ var parameter = parameters[i];
+ if (!IsConstantCompatible(parameter.Type))
+ {
+ continue;
+ }
+ var baseParameter = baseParameters[i];
+ if (HasConstantExpectedAttributeData(baseParameter) && !HasConstantExpectedAttributeData(parameter))
+ {
+ var diagnostic = parameter.DeclaringSyntaxReferences[0].GetSyntax().CreateDiagnostic(AttributeExpectedRule);
+ context.ReportDiagnostic(diagnostic);
+ }
+ }
+ }
+ }
private static void OnInvocation(OperationAnalysisContext context)
{
@@ -299,6 +340,12 @@ private static bool TryGetConstantExpectedAttributeData(IParameterSymbol paramet
return constantExpectedAttributeData is not null;
}
+ private static bool HasConstantExpectedAttributeData(IParameterSymbol parameter)
+ {
+ return parameter.GetAttributes()
+ .Any(attrData => IsConstantExpectedAttribute(attrData.AttributeClass));
+ }
+
private static bool IsConstantExpectedAttribute(INamedTypeSymbol namedType)
{
return namedType.Name.Equals(ConstantExpectedAttribute, StringComparison.Ordinal) &&
@@ -396,6 +443,7 @@ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(A
}
return (minConstant, maxConstant);
+
static object? ToObject(TypedConstant typedConstant)
{
if (typedConstant.IsNull)
@@ -406,6 +454,59 @@ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(A
}
}
+ private static bool TryGetMethodInterface(IMethodSymbol methodSymbol, [NotNullWhen(true)] out IMethodSymbol? interfaceMethodSymbol)
+ {
+ var explicitInterface = methodSymbol.ExplicitInterfaceImplementations
+ .FirstOrDefault(exInterface => methodSymbol.IsImplementationOfInterfaceMember(exInterface));
+ if (explicitInterface is not null)
+ {
+ interfaceMethodSymbol = explicitInterface;
+ return true;
+ }
+
+ if (methodSymbol.ContainingType != null)
+ {
+ foreach (INamedTypeSymbol interfaceSymbol in methodSymbol.ContainingType.AllInterfaces)
+ {
+ foreach (var interfaceMember in interfaceSymbol.GetMembers().OfType())
+ {
+ if (methodSymbol.IsImplementationOfInterfaceMember(interfaceMember))
+ {
+ interfaceMethodSymbol = interfaceMember;
+ return true;
+ }
+ }
+ }
+ }
+
+ interfaceMethodSymbol = null;
+ return false;
+ }
+
+ private static bool IsConstantCompatible(ITypeSymbol type)
+ {
+ return type.SpecialType switch
+ {
+ SpecialType.System_Char => true,
+ SpecialType.System_Byte => true,
+ SpecialType.System_UInt16 => true,
+ SpecialType.System_UInt32 => true,
+ SpecialType.System_UInt64 => true,
+ SpecialType.System_UIntPtr => true,
+ SpecialType.System_SByte => true,
+ SpecialType.System_Int16 => true,
+ SpecialType.System_Int32 => true,
+ SpecialType.System_Int64 => true,
+ SpecialType.System_IntPtr => true,
+ SpecialType.System_Single => true,
+ SpecialType.System_Double => true,
+ SpecialType.System_Boolean => true,
+ SpecialType.System_String => true,
+ SpecialType.None when type.TypeKind == TypeKind.TypeParameter => true,
+ _ => false,
+ };
+ }
+
protected abstract class DiagnosticHelper
{
public abstract Location? GetMinLocation(SyntaxNode attributeSyntax);
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 060689e670..3bad61592f 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 f9d8997d06..3043ca61b9 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 7f8fa51d45..764ca44e7a 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 81795168d7..f44c484e55 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 df447b6f14..661108a3aa 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 d8f123e9e8..2c9fcd7027 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 25b9dc80ce..d85ffb295c 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 0533bbe0bd..27e3742f8d 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 0cf97189d6..a13dc83b3b 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
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 c44cb66640..f4116a4e8d 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 987b5d3684..11f54868d1 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 149ace6158..0ec3d15e97 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
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
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 4345ad380a..6eb98b0597 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
@@ -192,6 +192,11 @@
Incorrect use of ConstantExpectedAttribute
+
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+
+ The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index d79d073620..ea6c42801e 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -14,21 +14,20 @@ public sealed class ConstantExpectedTests
{
[Theory]
[InlineData("char", "char.MinValue", "char.MaxValue")]
- [InlineData("byte", "byte.MinValue", "byte.MaxValue")]
- [InlineData("ushort", "ushort.MinValue", "ushort.MaxValue")]
- [InlineData("uint", "uint.MinValue", "uint.MaxValue")]
- [InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
- [InlineData("nuint", "uint.MinValue", "uint.MaxValue")]
[InlineData("sbyte", "sbyte.MinValue", "sbyte.MaxValue")]
[InlineData("short", "short.MinValue", "short.MaxValue")]
[InlineData("int", "int.MinValue", "int.MaxValue")]
[InlineData("long", "long.MinValue", "long.MaxValue")]
[InlineData("nint", "int.MinValue", "int.MaxValue")]
+ [InlineData("byte", "byte.MinValue", "byte.MaxValue")]
+ [InlineData("ushort", "ushort.MinValue", "ushort.MaxValue")]
+ [InlineData("uint", "uint.MinValue", "uint.MaxValue")]
+ [InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
+ [InlineData("nuint", "uint.MinValue", "uint.MaxValue")]
[InlineData("float", "float.MinValue", "float.MaxValue")]
[InlineData("double", "double.MinValue", "double.MaxValue")]
public static async Task TestConstantExpectedSupportedUnmanagedTypesAsync(string type, string minValue, string maxValue)
{
-
string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -65,7 +64,6 @@ public static void TestMethod7([ConstantExpected(Min=null, Max=null)] {type} val
[Fact]
public static async Task TestConstantExpectedSupportedComplexTypesAsync()
{
-
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -91,10 +89,63 @@ public static void TestMethodGeneric([ConstantExpected] T val)
await TestCSAsync(csInput);
}
- [Fact]
- public static async Task TestConstantExpectedUnsupportedTypesAsync()
+ [Theory]
+ [InlineData("char")]
+ [InlineData("sbyte")]
+ [InlineData("short")]
+ [InlineData("int")]
+ [InlineData("long")]
+ [InlineData("nint")]
+ [InlineData("byte")]
+ [InlineData("ushort")]
+ [InlineData("uint")]
+ [InlineData("ulong")]
+ [InlineData("nuint")]
+ [InlineData("float")]
+ [InlineData("double")]
+ [InlineData("string")]
+ public static async Task TestConstantExpectedSupportedComplex2TypesAsync(string type)
{
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public interface ITest
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public interface ITest2
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public abstract class AbstractTest
+ {{
+ public abstract T Method2(T operand1, [ConstantExpected] T operand2);
+ }}
+ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
+ {{
+ public {type} Method({type} operand1, {{|#0:{type} operand2|}}) => throw new NotImplementedException();
+ {type} ITest2<{type}>.Method({type} operand1, {{|#1:{type} operand2|}}) => throw new NotImplementedException();
+ public override {type} Method2({type} operand1, {{|#2:{type} operand2|}}) => throw new NotImplementedException();
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(0),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(1),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(2));
+ }
+
+ [Fact]
+ public static async Task TestConstantExpectedSupportedComplex3TypesAsync()
+ {
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -102,45 +153,101 @@ public static async Task TestConstantExpectedUnsupportedTypesAsync()
public class Test
{
- public static void TestMethodObject([{|#0:ConstantExpected|}] object val)
+ public interface ITest
{
+ T Method(T operand1, [ConstantExpected] T operand2);
}
- public static void TestMethodCustomClass([{|#1:ConstantExpected|}] Test val)
+ public interface ITest2
{
+ T Method(T operand1, [ConstantExpected] T operand2);
}
- public static void TestMethodDecimal([{|#2:ConstantExpected|}] decimal val)
+ public abstract class AbstractTest
{
+ public abstract T Method2(T operand1, [ConstantExpected] T operand2);
}
- public static void TestMethodByteArray([{|#3:ConstantExpected|}] byte[] val)
- {
- }
- public static void TestMethodGenericArray([{|#4:ConstantExpected|}] T[] val)
- {
- }
- public static void TestMethodValueTuple([{|#5:ConstantExpected|}] ValueTuple val)
+ public class GenericForward : AbstractTest, ITest, ITest2
{
+ public T Method(T operand1, {|#0:T operand2|}) => throw new NotImplementedException();
+ T ITest2.Method(T operand1, {|#1:T operand2|}) => throw new NotImplementedException();
+ public override T Method2(T operand1, {|#2:T operand2|}) => throw new NotImplementedException();
}
}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(0),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(1),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ .WithLocation(2));
+ }
+
+ [Theory]
+ [InlineData("", "", "object", "object")]
+ [InlineData("", "", "Test", "Test")]
+ [InlineData("", "", "Guid", "System.Guid")]
+ [InlineData("", "", "decimal", "decimal")]
+ [InlineData("", "", "byte[]", "byte[]")]
+ [InlineData("", "", "(int, long)", "(int, long)")]
+ [InlineData("", "", "T[]", "T[]")]
+ [InlineData("", "", "T[]", "T[]")]
+ public static async Task TestConstantExpectedUnsupportedTypesAsync(string classGeneric, string methodGeneric, string type, string diagnosticType)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test{classGeneric}
+{{
+ public static void TestMethod{methodGeneric}([{{|#0:ConstantExpected|}}] {type} val)
+ {{
+ }}
+}}
";
await TestCSAsync(csInput,
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
.WithLocation(0)
- .WithArguments("object"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
- .WithLocation(1)
- .WithArguments("Test"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
- .WithLocation(2)
- .WithArguments("decimal"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
- .WithLocation(3)
- .WithArguments("byte[]"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
- .WithLocation(4)
- .WithArguments("T[]"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
- .WithLocation(5)
- .WithArguments("(int, long)"));
+ .WithArguments(diagnosticType));
+ }
+
+ [Theory]
+ [InlineData("object")]
+ [InlineData("Test")]
+ [InlineData("Guid")]
+ [InlineData("decimal")]
+ [InlineData("byte[]")]
+ [InlineData("(int, long)")]
+ public static async Task TestConstantExpectedUnsupportedIgnoredComplexTypesAsync(string type)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public interface ITest
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public interface ITest2
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public abstract class AbstractTest
+ {{
+ public abstract T Method2(T operand1, [ConstantExpected] T operand2);
+ }}
+ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
+ {{
+ public {type} Method({type} operand1, {type} operand2) => throw new NotImplementedException();
+ {type} ITest2<{type}>.Method({type} operand1, {type} operand2) => throw new NotImplementedException();
+ public override {type} Method2({type} operand1, {type} operand2) => throw new NotImplementedException();
+ }}
+}}
+";
+ await TestCSAsync(csInput);
}
[Theory]
@@ -193,6 +300,42 @@ await TestCSAsync(csInput,
.WithArguments("Max", type));
}
+ [Theory]
+ [InlineData("", "", "string", "true", "false", "string")]
+ [InlineData("", "", "T", "\"min\"", "false", "generic")]
+ [InlineData("", "", "T", "\"min\"", "false", "generic")]
+ public static async Task TestConstantExpectedIncompatibleConstantMinMaxTypeErrorAsync(string classGeneric, string methodGeneric, string type, string badMinValue, string badMaxValue, string diagnosticText)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test{classGeneric}
+{{
+ public static void TestMethod1{methodGeneric}([{{|#0:ConstantExpected(Min = {badMinValue})|}}] {type} val)
+ {{
+ }}
+ public static void TestMethod2{methodGeneric}([{{|#1:ConstantExpected(Min = {badMinValue}, Max = {badMaxValue})|}}] {type} val)
+ {{
+ }}
+ public static void TestMethod3{methodGeneric}([{{|#2:ConstantExpected(Max = {badMaxValue})|}}] {type} val)
+ {{
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(0)
+ .WithArguments(diagnosticText),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(1)
+ .WithArguments(diagnosticText),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
+ .WithLocation(2)
+ .WithArguments(diagnosticText));
+ }
+
[Theory]
[InlineData("char", "'Z'", "'A'")]
[InlineData("sbyte", "1", "0")]
@@ -226,149 +369,24 @@ await TestCSAsync(csInput,
.WithLocation(0));
}
- [Fact]
- public static async Task TestConstantExpectedIncompatibleConstantMinMaxTypeErrorAsync()
- {
- string csInput = @"
-using System;
-using System.Diagnostics.CodeAnalysis;
-#nullable enable
-
-public class Test
-{
- public static void TestMethodString1([{|#0:ConstantExpected(Min = true)|}] string val)
- {
- }
- public static void TestMethodString2([{|#1:ConstantExpected(Min = true, Max = 5f)|}] string val)
- {
- }
- public static void TestMethodString3([{|#2:ConstantExpected(Max = 10.0)|}] string val)
- {
- }
-
- public static void TestMethodGeneric1([{|#3:ConstantExpected(Min = ""min"")|}] T val)
- {
- }
- public static void TestMethodGeneric2([{|#4:ConstantExpected(Min = ""min"", Max = '1')|}] T val)
- {
- }
- public static void TestMethodGeneric3([{|#5:ConstantExpected(Max = ulong.MaxValue)|}] T val)
- {
- }
- public static class GenenricClass
- {
- public static void TestMethodGeneric1([{|#6:ConstantExpected(Min = ""min"")|}] T val)
- {
- }
- public static void TestMethodGeneric2([{|#7:ConstantExpected(Min = ""min"", Max = ""a"")|}] T val)
- {
- }
- public static void TestMethodGeneric3([{|#8:ConstantExpected(Max = ""a"")|}] T val)
- {
- }
- }
-}
-";
- await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(0)
- .WithArguments("string"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(1)
- .WithArguments("string"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(2)
- .WithArguments("string"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(3)
- .WithArguments("generic"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(4)
- .WithArguments("generic"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(5)
- .WithArguments("generic"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(6)
- .WithArguments("generic"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(7)
- .WithArguments("generic"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(8)
- .WithArguments("generic"));
- }
-
- [Fact]
- public static async Task TestConstantExpectedInvalidBoundsAsync()
- {
- string[][] setArray = {
- new[]
- {
- "byte", byte.MinValue.ToString(), byte.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "ushort", ushort.MinValue.ToString(), ushort.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "uint", uint.MinValue.ToString(), uint.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "ulong", ulong.MinValue.ToString(), ulong.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "-1", "-1"
- },
- new[]
- {
- "nuint", uint.MinValue.ToString(), uint.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "sbyte", sbyte.MinValue.ToString(), sbyte.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "short", short.MinValue.ToString(), short.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "int", int.MinValue.ToString(), int.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "long", long.MinValue.ToString(), long.MaxValue.ToString(),
- "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue"
- },
- new[]
- {
- "nint", int.MinValue.ToString(), int.MaxValue.ToString(),
- "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue"
- },
- new[]
- {
- "float", float.MinValue.ToString(), float.MaxValue.ToString(),
- "double.MinValue", "double.MinValue", "double.MaxValue", "double.MaxValue"
- }
- };
-
- foreach (string[] set in setArray)
- {
- await TestTheoryAsync(set[0], set[1], set[2], set[3], set[4], set[5], set[6]);
- }
-
- static async Task TestTheoryAsync(string type, string min, string max, string min1, string min2, string max2,
+ [Theory]
+ [InlineData("sbyte", sbyte.MinValue, sbyte.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("int", int.MinValue, int.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("long", long.MinValue, long.MaxValue, "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue")]
+ [InlineData("nint", int.MinValue, int.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("byte", byte.MinValue, byte.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("ushort", ushort.MinValue, ushort.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("uint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("ulong", ulong.MinValue, ulong.MaxValue, "long.MinValue", "long.MinValue", "-1", "-1")]
+ [InlineData("nuint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
+ [InlineData("float", float.MinValue, float.MaxValue, "double.MinValue", "double.MinValue", "double.MaxValue", "double.MaxValue")]
+ public static async Task TestConstantExpectedInvalidBoundsAsync(string type, object min, object max, string min1, string min2, string max2,
string max3)
- {
- string csInput = @$"
+ {
+ string minString = min.ToString();
+ string maxString = max.ToString();
+ string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
@@ -392,53 +410,51 @@ public static void TestMethod5([ConstantExpected({{|#6:Min = {min2}|}}, {{|#7:Ma
}}
}}
";
- await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(0)
- .WithArguments("Min", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(1)
- .WithArguments("Min", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(2)
- .WithArguments("Max", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(3)
- .WithArguments("Max", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
- .WithLocation(4)
- .WithArguments("Min", type),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(5)
- .WithArguments("Max", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
- .WithLocation(6)
- .WithArguments("Min", min, max),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
- .WithLocation(7)
- .WithArguments("Max", type));
- }
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(0)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(1)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(2)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(3)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(4)
+ .WithArguments("Min", type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(5)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ .WithLocation(6)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ .WithLocation(7)
+ .WithArguments("Max", type));
}
[Theory]
[InlineData("char", "'A'", "'Z'", "'A'", "(char)('A'+'\\u0001')")]
- [InlineData("byte", "10", "20", "10", "2*5")]
- [InlineData("ushort", "10", "20", "10", "2*5")]
- [InlineData("uint", "10", "20", "10", "2*5")]
- [InlineData("ulong", "10", "20", "10", "2*5")]
- [InlineData("nuint", "10", "20", "10", "2*5")]
[InlineData("sbyte", "10", "20", "10", "2*5")]
[InlineData("short", "10", "20", "10", "2*5")]
[InlineData("int", "10", "20", "10", "2*5")]
[InlineData("long", "10", "20", "10", "2*5")]
[InlineData("nint", "10", "20", "10", "2*5")]
+ [InlineData("byte", "10", "20", "10", "2*5")]
+ [InlineData("ushort", "10", "20", "10", "2*5")]
+ [InlineData("uint", "10", "20", "10", "2*5")]
+ [InlineData("ulong", "10", "20", "10", "2*5")]
+ [InlineData("nuint", "10", "20", "10", "2*5")]
[InlineData("float", "10", "20", "10", "2*5")]
[InlineData("double", "10", "20", "10", "2*5")]
[InlineData("bool", "true", "true", "true", "!false")]
[InlineData("string", "null", "null", "\"true\"", "\"false\"")]
public static async Task TestArgumentConstantAsync(string type, string minValue, string maxValue, string value, string expression)
{
-
string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -478,37 +494,50 @@ public static void TestMethodGeneric([ConstantExpected] T val)
await TestCSAsync(csInput);
}
- [Fact]
- public static async Task TestArgumentNotConstantAsync()
+ [Theory]
+ [InlineData("char")]
+ [InlineData("sbyte")]
+ [InlineData("short")]
+ [InlineData("int")]
+ [InlineData("long")]
+ [InlineData("nint")]
+ [InlineData("byte")]
+ [InlineData("ushort")]
+ [InlineData("uint")]
+ [InlineData("ulong")]
+ [InlineData("nuint")]
+ [InlineData("float")]
+ [InlineData("double")]
+ [InlineData("string")]
+ public static async Task TestArgumentNotConstantAsync(string type)
{
-
- string csInput = @"
+ string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
public class Test
-{
- public static void TestMethod(int nonConstant)
- {
- TestMethodWithConstant({|#0:nonConstant|});
- TestMethodGeneric({|#1:nonConstant|});
- GenenricClass.TestMethodGeneric({|#2:nonConstant|});
- }
- public static void TestMethodWithConstant([ConstantExpected] int val)
- {
- }
+{{
+ public static void TestMethod({type} nonConstant)
+ {{
+ TestMethodWithConstant({{|#0:nonConstant|}});
+ TestMethodGeneric<{type}>({{|#1:nonConstant|}});
+ GenenricClass<{type}>.TestMethodGeneric({{|#2:nonConstant|}});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val)
+ {{
+ }}
public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
+ {{
+ }}
public static class GenenricClass
- {
+ {{
public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
- }
-}
+ {{
+ }}
+ }}
+}}
";
await TestCSAsync(csInput,
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
@@ -519,77 +548,47 @@ await TestCSAsync(csInput,
.WithLocation(2));
}
- [Fact]
- public static async Task TestArgumentStringNotConstantAsync()
- {
-
- string csInput = @"
-using System;
-using System.Diagnostics.CodeAnalysis;
-#nullable enable
-
-public class Test
-{
- public static void TestMethod(string nonConstant)
- {
- TestMethodWithConstant({|#0:nonConstant|});
- TestMethodGeneric({|#1:nonConstant|});
- GenenricClass.TestMethodGeneric({|#2:nonConstant|});
- }
- public static void TestMethodWithConstant([ConstantExpected] string val)
- {
- }
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
-
- public static class GenenricClass
- {
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
- }
-}
-";
- await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(0),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(1),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
- .WithLocation(2));
- }
-
- [Fact]
- public static async Task TestArgumentOutOfRangeConstantAsync()
+ [Theory]
+ [InlineData("char", "'B'", "'C'", "'D'")]
+ [InlineData("sbyte", "3", "4", "5")]
+ [InlineData("short", "3", "4", "5")]
+ [InlineData("int", "3", "4", "5")]
+ [InlineData("long", "3", "4", "5")]
+ [InlineData("nint", "3", "4", "5")]
+ [InlineData("byte", "3", "4", "5")]
+ [InlineData("ushort", "3", "4", "5")]
+ [InlineData("uint", "3", "4", "5")]
+ [InlineData("ulong", "3", "4", "5")]
+ [InlineData("nuint", "3", "4", "5")]
+ [InlineData("float", "3", "4", "5")]
+ [InlineData("double", "3", "4", "5")]
+ public static async Task TestArgumentOutOfBoundsConstantAsync(string type, string min, string max, string testValue)
{
-
- string csInput = @"
+ string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
public class Test
-{
+{{
public static void TestMethod()
- {
- TestMethodWithConstant({|#0:11|});
- }
- public static void TestMethodWithConstant([ConstantExpected(Min=0, Max=10)] int val)
- {
- }
-}
+ {{
+ TestMethodWithConstant({{|#0:{testValue}|}});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected(Min={min}, Max={max})] {type} val)
+ {{
+ }}
+}}
";
await TestCSAsync(csInput,
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantOutOfBoundsRule)
.WithLocation(0)
- .WithArguments("0", "10"));
+ .WithArguments(min.Trim('\''), max.Trim('\'')));
}
[Fact]
public static async Task TestArgumentInvalidGenericTypeParameterConstantAsync()
{
-
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -617,36 +616,45 @@ public static void TestMethodGeneric([ConstantExpected] T val)
await TestCSAsync(csInput);
}
- [Fact]
- public static async Task TestConstantCompositionAsync()
+ [Theory]
+ [InlineData("char", "'B'", "'C'")]
+ [InlineData("sbyte", "3", "4")]
+ [InlineData("short", "3", "4")]
+ [InlineData("int", "3", "4")]
+ [InlineData("long", "3", "4")]
+ [InlineData("nint", "3", "4")]
+ [InlineData("byte", "3", "4")]
+ [InlineData("ushort", "3", "4")]
+ [InlineData("uint", "3", "4")]
+ [InlineData("ulong", "3", "4")]
+ [InlineData("nuint", "3", "4")]
+ [InlineData("float", "3", "4")]
+ [InlineData("double", "3", "4")]
+ public static async Task TestConstantCompositionAsync(string type, string min, string max)
{
-
- string csInput = @"
+ string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
public class Test
-{
- public static void TestMethod([ConstantExpected] int constant)
- {
+{{
+ public static void TestMethod([ConstantExpected] {type} constant)
+ {{
TestMethodWithConstant(constant);
- }
- public static void TestMethodWithConstant([ConstantExpected] int val)
- {
- }
- public static void TestMethod2([ConstantExpected(Min = 10, Max = 20)] int constant)
- {
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val)
+ {{
+ }}
+ public static void TestMethodConstrained([ConstantExpected(Min = {min}, Max = {max})] {type} constant)
+ {{
TestMethodWithConstant(constant);
- TestMethod2WithConstrainedConstant(constant);
- }
- public static void TestMethod2WithConstant([ConstantExpected] int val)
- {
- }
- public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
- {
- }
-}
+ TestMethodWithConstrainedConstant(constant);
+ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val)
+ {{
+ }}
+}}
";
await TestCSAsync(csInput);
}
@@ -654,7 +662,6 @@ public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10
[Fact]
public static async Task TestConstantCompositionStringAsync()
{
-
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -674,10 +681,47 @@ public static void TestMethodWithConstant([ConstantExpected] string val)
await TestCSAsync(csInput);
}
- [Fact]
- public static async Task TestConstantCompositionOutOfRangeAsync()
+ [Theory]
+ [InlineData("char", "'B'", "'C'", "'D'")]
+ [InlineData("sbyte", "3", "4", "5")]
+ [InlineData("short", "3", "4", "5")]
+ [InlineData("int", "3", "4", "5")]
+ [InlineData("long", "3", "4", "5")]
+ [InlineData("nint", "3", "4", "5")]
+ [InlineData("byte", "3", "4", "5")]
+ [InlineData("ushort", "3", "4", "5")]
+ [InlineData("uint", "3", "4", "5")]
+ [InlineData("ulong", "3", "4", "5")]
+ [InlineData("nuint", "3", "4", "5")]
+ [InlineData("float", "3", "4", "5")]
+ [InlineData("double", "3", "4", "5")]
+ public static async Task TestConstantCompositionOutOfBoundsAsync(string type, string min, string max, string outOfBoundMax)
{
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+public class Test
+{{
+ public static void TestMethodConstrained([{{|#0:ConstantExpected(Min = {min}, Max = {outOfBoundMax})|}}] {type} constant)
+ {{
+ TestMethodWithConstrainedConstant(constant);
+ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val)
+ {{
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeOutOfBoundsRule)
+ .WithLocation(0)
+ .WithArguments(min.Trim('\''), max.Trim('\'')));
+ }
+
+ [Fact]
+ public static async Task TestConstantCompositionNotSameTypeAsync()
+ {
string csInput = @"
using System;
using System.Diagnostics.CodeAnalysis;
@@ -696,13 +740,6 @@ public static void TestMethod([{|#1:ConstantExpected|}] short constant)
public static void TestMethodWithConstant([ConstantExpected] int val)
{
}
- public static void TestMethod2([{|#2:ConstantExpected(Min = 10, Max = 21)|}] int constant)
- {
- TestMethod2WithConstrainedConstant(constant);
- }
- public static void TestMethod2WithConstrainedConstant([ConstantExpected(Min = 10, Max = 20)] int val)
- {
- }
}
";
await TestCSAsync(csInput,
@@ -711,10 +748,7 @@ await TestCSAsync(csInput,
.WithArguments("int"),
VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeNotSameTypeRule)
.WithLocation(1)
- .WithArguments("int"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeOutOfBoundsRule)
- .WithLocation(2)
- .WithArguments("10", "20"));
+ .WithArguments("int"));
}
private static async Task TestCSAsync(string source, params DiagnosticResult[] diagnosticResults)
From d4fe364fbbc701e7fe8a1f268543693541807ba0 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:21:31 +0800
Subject: [PATCH 06/27] run pack command
---
.../Core/AnalyzerReleases.Unshipped.md | 2 +
.../Microsoft.CodeAnalysis.NetAnalyzers.md | 24 ++++++++++++
.../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 38 +++++++++++++++++++
src/NetAnalyzers/RulesMissingDocumentation.md | 2 +
.../DiagnosticCategoryAndIdRanges.txt | 2 +-
5 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
index 5d35f49a65..ae2939228d 100644
--- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
+++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
@@ -6,5 +6,7 @@ Rule ID | Category | Severity | Notes
--------|----------|----------|-------
CA1849 | Performance | Disabled | UseAsyncMethodInAsyncContext, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1849)
CA1850 | Performance | Info | PreferHashDataOverComputeHashAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1850)
+CA1860 | Performance | Error | ConstantExpectedAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860)
+CA1861 | Performance | Warning | ConstantExpectedAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860)
CA5404 | Security | Disabled | DoNotDisableTokenValidationChecks, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca5404)
CA5405 | Security | Disabled | DoNotAlwaysSkipTokenValidationInDelegates, [Documentation](https://docs.microsoft.com/visualstudio/code-quality/ca5405)
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
index cb70695cd5..b65f0106c0 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
@@ -1476,6 +1476,30 @@ It is more efficient to use the static 'HashData' method over creating and manag
|CodeFix|True|
---
+## [CA1860](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860): Incorrect use of ConstantExpectedAttribute
+
+ConstantExpectedAttribute is not applied correctly on the paramter.
+
+|Item|Value|
+|-|-|
+|Category|Performance|
+|Enabled|True|
+|Severity|Error|
+|CodeFix|False|
+---
+
+## [CA1861](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861): Constant is expected for the parameter
+
+The parameter expects a constant for best performance.
+
+|Item|Value|
+|-|-|
+|Category|Performance|
+|Enabled|True|
+|Severity|Warning|
+|CodeFix|False|
+---
+
## [CA2000](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000): Dispose objects before losing scope
If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead.
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index 0560a44240..043b9c8b6a 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -246,6 +246,44 @@
]
}
},
+ "CA1860": {
+ "id": "CA1860",
+ "shortDescription": "Incorrect use of ConstantExpectedAttribute",
+ "fullDescription": "ConstantExpectedAttribute is not applied correctly on the paramter.",
+ "defaultLevel": "error",
+ "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860",
+ "properties": {
+ "category": "Performance",
+ "isEnabledByDefault": true,
+ "typeName": "CSharpConstantExpectedAnalyzer",
+ "languages": [
+ "C#"
+ ],
+ "tags": [
+ "Telemetry",
+ "EnabledRuleInAggressiveMode"
+ ]
+ }
+ },
+ "CA1861": {
+ "id": "CA1861",
+ "shortDescription": "Constant is expected for the parameter",
+ "fullDescription": "The parameter expects a constant for best performance.",
+ "defaultLevel": "warning",
+ "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861",
+ "properties": {
+ "category": "Performance",
+ "isEnabledByDefault": true,
+ "typeName": "CSharpConstantExpectedAnalyzer",
+ "languages": [
+ "C#"
+ ],
+ "tags": [
+ "Telemetry",
+ "EnabledRuleInAggressiveMode"
+ ]
+ }
+ },
"CA2014": {
"id": "CA2014",
"shortDescription": "Do not use stackalloc in loops",
diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md
index 75e0f77588..1092b22db2 100644
--- a/src/NetAnalyzers/RulesMissingDocumentation.md
+++ b/src/NetAnalyzers/RulesMissingDocumentation.md
@@ -2,3 +2,5 @@
Rule ID | Missing Help Link | Title |
--------|-------------------|-------|
+CA1860 | | Incorrect use of ConstantExpectedAttribute |
+CA1861 | | Constant is expected for the parameter |
diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
index a94aba62d9..c412574b5c 100644
--- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
+++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt
@@ -12,7 +12,7 @@
Design: CA2210, CA1000-CA1070
Globalization: CA2101, CA1300-CA1310
Mobility: CA1600-CA1601
-Performance: HA, CA1800-CA1850
+Performance: HA, CA1800-CA1850, CA1860-CA1861
Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405
Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2258
Naming: CA1700-CA1727
From 5f8922f87d1a913320606966c3de7cc1f9ebc53c Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Fri, 25 Feb 2022 19:22:11 +0800
Subject: [PATCH 07/27] Reorganize and combine some rules.
Fill in missing cases in tests.
---
.../MicrosoftNetCoreAnalyzersResources.resx | 28 +-
...onstantExpectedAnalyzer.UnmanagedHelper.cs | 143 ++-----
.../Performance/ConstantExpectedAnalyzer.cs | 284 ++++++-------
.../MicrosoftNetCoreAnalyzersResources.cs.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.de.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.es.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.fr.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.it.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.ja.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.ko.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.pl.xlf | 50 +--
...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.ru.xlf | 50 +--
.../MicrosoftNetCoreAnalyzersResources.tr.xlf | 50 +--
...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 50 +--
...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 50 +--
.../Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +-
.../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +-
.../Performance/ConstantExpectedTests.cs | 388 ++++++++----------
19 files changed, 601 insertions(+), 896 deletions(-)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index 30cdfd6547..73df559709 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1844,36 +1844,30 @@
Constant is expected for the parameter
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' condition does not match parameter type of '{1}'.
-
-
- The Min/Max condition can only be null for '{0}' types.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
-
- The argument should be a constant.
+
+ The constant is not of the same '{0}' type as the parameter
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
+
+ The argument should be a constant for optimal performance.The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
\ No newline at end of file
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
index 053763ed38..93c3be961c 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
@@ -21,32 +21,32 @@ static UnmanagedHelper()
{
if (typeof(T) == typeof(long))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertInt64, TryTransformInt64);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformInt64);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(ulong))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertUInt64, TryTransformUInt64);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformUInt64);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(float))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertSingle, TryTransformSingle);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformSingle);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(double))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertDouble, TryTransformDouble);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformDouble);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(char))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertChar, TryTransformChar);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformChar);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
else if (typeof(T) == typeof(bool))
{
- var helper = new UnmanagedHelper.TransformHelper(TryConvertBoolean, TryTransformBoolean);
+ var helper = new UnmanagedHelper.TransformHelper(TryTransformBoolean);
_instance = new ConstantExpectedParameterFactory((TransformHelper)(object)helper);
}
}
@@ -57,15 +57,12 @@ public static bool Validate(IParameterSymbol parameterSymbol, AttributeData attr
=> Instance.Validate(parameterSymbol, attributeData, typeMin, typeMax, diagnosticHelper, out diagnostics);
public delegate bool TryTransform(object constant, out T value, out bool isInvalid);
- public delegate bool TryConvert(object? constant, out T value);
public sealed class TransformHelper
{
private readonly TryTransform _tryTransform;
- private readonly TryConvert _convert;
- public TransformHelper(TryConvert convert, TryTransform tryTransform)
+ public TransformHelper(TryTransform tryTransform)
{
- _convert = convert;
_tryTransform = tryTransform;
}
@@ -105,7 +102,7 @@ public bool TryTransformMax(object constant, out T value, ref ErrorKind errorFla
}
return false;
}
- public bool TryConvert(object? val, out T value) => _convert(val, out value);
+ public bool TryConvert(object val, out T value) => _tryTransform(val, out value, out _);
}
public sealed class ConstantExpectedParameterFactory
@@ -136,7 +133,7 @@ public bool TryCreate(IParameterSymbol parameterSymbol, AttributeData attributeD
return false;
}
- parameter = new UnmanagedConstantExpectedParameter(parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax(), minValue, maxValue, _helper);
+ parameter = new UnmanagedConstantExpectedParameter(parameterSymbol, minValue, maxValue, _helper);
return true;
}
@@ -179,7 +176,7 @@ private bool IsValidMinMax(AttributeData attributeData, T typeMin, T typeMax, ou
public sealed class UnmanagedConstantExpectedParameter : ConstantExpectedParameter
{
private readonly TransformHelper _helper;
- public UnmanagedConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax, T min, T max, TransformHelper helper) : base(parameter, attributeSyntax)
+ public UnmanagedConstantExpectedParameter(IParameterSymbol parameter, T min, T max, TransformHelper helper) : base(parameter)
{
Min = min;
Max = max;
@@ -189,12 +186,12 @@ public UnmanagedConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode
public T Min { get; }
public T Max { get; }
- public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, IArgumentOperation argument, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
{
if (Parameter.Type.SpecialType != subsetCandidate.Parameter.Type.SpecialType ||
subsetCandidate is not UnmanagedConstantExpectedParameter subsetCandidateTParameter)
{
- validationDiagnostics = Diagnostic.Create(AttributeNotSameTypeRule, subsetCandidate.AttributeSyntax.GetLocation(), Parameter.Type.ToDisplayString());
+ validationDiagnostics = Diagnostic.Create(CA1861.ConstantInvalidConstantRule, argument.Syntax.GetLocation(), Parameter.Type.ToDisplayString());
return false;
}
@@ -204,22 +201,23 @@ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter su
validationDiagnostics = null;
return true;
}
- validationDiagnostics = Diagnostic.Create(AttributeOutOfBoundsRule, subsetCandidateTParameter.AttributeSyntax.GetLocation(), Min.ToString(), Max.ToString());
+ validationDiagnostics = Diagnostic.Create(CA1861.ConstantOutOfBoundsRule, argument.Syntax.GetLocation(), Min.ToString(), Max.ToString());
return false;
}
public override bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
{
- if (_helper.TryConvert(constant, out T value))
+ if (constant is not null && _helper.TryConvert(constant, out T value))
{
if (!_helper.IsLessThan(value, Min) && !_helper.IsLessThan(Max, value))
{
validationDiagnostics = null;
return true;
}
+ validationDiagnostics = argument.CreateDiagnostic(CA1861.ConstantOutOfBoundsRule, Min.ToString(), Max.ToString());
+ return false;
}
-
- validationDiagnostics = argument.CreateDiagnostic(ConstantOutOfBoundsRule, Min.ToString(), Max.ToString());
+ validationDiagnostics = argument.CreateDiagnostic(CA1861.ConstantInvalidConstantRule, Parameter.Type.ToDisplayString());
return false;
}
}
@@ -262,17 +260,6 @@ private static bool TryConvertUnsignedInteger(object constant, out ulong integer
return true;
}
- private static bool TryConvertInt64(object? constant, out long value)
- {
- if (constant is not null)
- {
- value = Convert.ToInt64(constant);
- return true;
- }
- value = default;
- return false;
- }
-
private static bool TryTransformInt64(object constant, out long value, out bool isInvalid)
{
bool isValidSigned = TryConvertSignedInteger(constant, out value);
@@ -287,16 +274,6 @@ private static bool TryTransformInt64(object constant, out long value, out bool
}
return isValidSigned;
}
- private static bool TryConvertUInt64(object? constant, out ulong value)
- {
- if (constant is not null)
- {
- value = Convert.ToUInt64(constant);
- return true;
- }
- value = default;
- return false;
- }
private static bool TryTransformUInt64(object constant, out ulong value, out bool isInvalid)
{
bool isValidUnsigned = TryConvertUnsignedInteger(constant, out value);
@@ -318,31 +295,17 @@ private static bool TryTransformChar(object constant, out char value, out bool i
{
if (constant is string or bool)
{
- value = default;
- isInvalid = true;
- return false;
+ return Invalid(out value, out isInvalid);
}
value = Convert.ToChar(constant);
}
catch
{
- value = default;
- isInvalid = true;
- return false;
+ return Invalid(out value, out isInvalid);
}
isInvalid = false;
return true;
}
- private static bool TryConvertChar(object? constant, out char value)
- {
- if (constant is not null)
- {
- value = Convert.ToChar(constant);
- return true;
- }
- value = default;
- return false;
- }
private static bool TryTransformBoolean(object constant, out bool value, out bool isInvalid)
{
@@ -352,83 +315,35 @@ private static bool TryTransformBoolean(object constant, out bool value, out boo
isInvalid = false;
return true;
}
- isInvalid = true;
- value = default;
- return false;
- }
- private static bool TryConvertBoolean(object? constant, out bool value)
- {
- if (constant is not null)
- {
- value = (bool)constant;
- return true;
- }
- value = default;
- return false;
+ return Invalid(out value, out isInvalid);
}
private static bool TryTransformSingle(object constant, out float value, out bool isInvalid)
{
- try
- {
- if (constant is string or bool)
- {
- value = default;
- isInvalid = true;
- return false;
- }
- value = Convert.ToSingle(constant);
- }
- catch
+ if (constant is string or bool)
{
- value = default;
- isInvalid = true;
- return false;
+ return Invalid(out value, out isInvalid);
}
+ value = Convert.ToSingle(constant);
isInvalid = false;
return true;
}
- private static bool TryConvertSingle(object? constant, out float value)
- {
- if (constant is not null)
- {
- value = Convert.ToSingle(constant);
- return true;
- }
- value = default;
- return false;
- }
-
private static bool TryTransformDouble(object constant, out double value, out bool isInvalid)
{
- try
+ if (constant is string or bool)
{
- if (constant is string or bool)
- {
- value = default;
- isInvalid = true;
- return false;
- }
- value = Convert.ToDouble(constant);
- }
- catch
- {
- value = default;
- isInvalid = true;
- return false;
+ return Invalid(out value, out isInvalid);
}
+ value = Convert.ToDouble(constant);
isInvalid = false;
return true;
}
- private static bool TryConvertDouble(object? constant, out double value)
+
+ private static bool Invalid(out T value, out bool isInvalid) where T : unmanaged
{
- if (constant is not null)
- {
- value = Convert.ToDouble(constant);
- return true;
- }
value = default;
+ isInvalid = true;
return false;
}
}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index a828714f6f..bb75b25814 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -15,8 +15,6 @@ namespace Microsoft.NetCore.Analyzers.Performance
using static MicrosoftNetCoreAnalyzersResources;
public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
{
- internal const string CA1860 = nameof(CA1860);
- internal const string CA1861 = nameof(CA1861);
protected static readonly string ConstantExpectedAttribute = nameof(ConstantExpectedAttribute);
protected static readonly string ConstantExpected = nameof(ConstantExpected);
private static readonly LocalizableString s_localizableApplicationTitle = CreateLocalizableResourceString(nameof(ConstantExpectedApplicationTitle));
@@ -24,108 +22,101 @@ public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
private static readonly LocalizableString s_localizableUsageTitle = CreateLocalizableResourceString(nameof(ConstantExpectedUsageTitle));
private static readonly LocalizableString s_localizableUsageDescription = CreateLocalizableResourceString(nameof(ConstantExpectedUsageDescription));
- internal static readonly DiagnosticDescriptor InvalidTypeRule = DiagnosticDescriptorHelper.Create(
- CA1860,
- s_localizableApplicationTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedInvalidTypeMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildError,
- description: s_localizableApplicationDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor IncompatibleConstantTypeRule = DiagnosticDescriptorHelper.Create(
- CA1860,
- s_localizableApplicationTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedIncompatibleConstantTypeMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildError,
- description: s_localizableApplicationDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor IncompatibleConstantForMinMaxRule = DiagnosticDescriptorHelper.Create(
- CA1860,
- s_localizableApplicationTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedIncompatibleConstantMinMaxMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildError,
- description: s_localizableApplicationDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor InvalidBoundsRule = DiagnosticDescriptorHelper.Create(
- CA1860,
- s_localizableApplicationTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedInvalidBoundsMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildError,
- description: s_localizableApplicationDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor InvertedRangeRule = DiagnosticDescriptorHelper.Create(
- CA1860,
- s_localizableApplicationTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedInvertedRangeMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildError,
- description: s_localizableApplicationDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor ConstantOutOfBoundsRule = DiagnosticDescriptorHelper.Create(
- CA1861,
- s_localizableUsageTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedOutOfBoundsMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildWarning,
- description: s_localizableUsageDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor ConstantNotConstantRule = DiagnosticDescriptorHelper.Create(
- CA1861,
- s_localizableUsageTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedNotConstantMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildWarning,
- description: s_localizableUsageDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor AttributeOutOfBoundsRule = DiagnosticDescriptorHelper.Create(
- CA1861,
- s_localizableUsageTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedAttributeOutOfBoundsMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildWarning,
- description: s_localizableUsageDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor AttributeExpectedRule = DiagnosticDescriptorHelper.Create(
- CA1861,
- s_localizableUsageTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedAttributExpectedMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildWarning,
- description: s_localizableUsageDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
-
- internal static readonly DiagnosticDescriptor AttributeNotSameTypeRule = DiagnosticDescriptorHelper.Create(
- CA1861,
- s_localizableUsageTitle,
- CreateLocalizableResourceString(nameof(ConstantExpectedAttributeNotSameTypeMessage)),
- DiagnosticCategory.Performance,
- RuleLevel.BuildWarning,
- description: s_localizableUsageDescription,
- isPortedFxCopRule: false,
- isDataflowRule: false);
+ internal static class CA1860
+ {
+ internal const string Id = nameof(CA1860);
+ internal const RuleLevel Level = RuleLevel.BuildError;
+ internal static readonly DiagnosticDescriptor UnsupportedTypeRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedNotSupportedMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor IncompatibleConstantTypeRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedIncompatibleConstantTypeMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor InvalidBoundsRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvalidBoundsMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor InvertedRangeRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableApplicationTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvertedRangeMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableApplicationDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+ }
+
+ internal static class CA1861
+ {
+ internal const string Id = nameof(CA1861);
+ internal const RuleLevel Level = RuleLevel.BuildWarning;
+
+ internal static readonly DiagnosticDescriptor ConstantOutOfBoundsRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedOutOfBoundsMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor ConstantNotConstantRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedNotConstantMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor ConstantInvalidConstantRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedInvalidMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+
+ internal static readonly DiagnosticDescriptor AttributeExpectedRule = DiagnosticDescriptorHelper.Create(
+ Id,
+ s_localizableUsageTitle,
+ CreateLocalizableResourceString(nameof(ConstantExpectedAttributExpectedMessage)),
+ DiagnosticCategory.Performance,
+ Level,
+ description: s_localizableUsageDescription,
+ isPortedFxCopRule: false,
+ isDataflowRule: false);
+ }
public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(
- InvalidTypeRule, IncompatibleConstantTypeRule, IncompatibleConstantForMinMaxRule, InvalidBoundsRule, InvertedRangeRule,
- ConstantOutOfBoundsRule, ConstantNotConstantRule, AttributeOutOfBoundsRule, AttributeExpectedRule, AttributeNotSameTypeRule);
+ CA1860.UnsupportedTypeRule, CA1860.IncompatibleConstantTypeRule,
+ CA1860.InvalidBoundsRule, CA1860.InvertedRangeRule,
+ CA1861.ConstantOutOfBoundsRule, CA1861.ConstantInvalidConstantRule,
+ CA1861.ConstantNotConstantRule, CA1861.AttributeExpectedRule);
protected abstract DiagnosticHelper Helper { get; }
@@ -167,7 +158,7 @@ static void CheckAttribute(SymbolAnalysisContext context, ImmutableArray.Validate(parameterSymbol, attributeData, false, true, Helper, out diagnostics);
case SpecialType.System_String:
- return StringConstantExpectedParameter.Validate(attributeData, out diagnostics);
+ return Validate(parameterSymbol, attributeData, Helper, out diagnostics);
case SpecialType.None when parameterSymbol.Type.TypeKind == TypeKind.TypeParameter:
- return ValidateGenericConstantCase(attributeData, out diagnostics);
+ return Validate(parameterSymbol, attributeData, Helper, out diagnostics);
default:
diagnostics = Helper.ParameterIsInvalid(parameterSymbol.Type.ToDisplayString(), attributeData.ApplicationSyntaxReference.GetSyntax());
return false;
}
}
- private bool ValidateGenericConstantCase(AttributeData attributeData, out ImmutableArray diagnostics)
- {
- var (min, max) = GetAttributeConstants(attributeData);
- // Ensure min max is unassigned/null
- if (min is not null || max is not null)
- {
- diagnostics = ImmutableArray.Create(
- Diagnostic.Create(IncompatibleConstantForMinMaxRule,
- attributeData.ApplicationSyntaxReference.GetSyntax().GetLocation(),
- "generic"));
- return false;
- }
- diagnostics = ImmutableArray.Empty;
- return true;
- }
private static bool TryGetConstantExpectedAttributeData(IParameterSymbol parameter, [NotNullWhen(true)] out AttributeData? attributeData)
{
@@ -356,28 +332,26 @@ private static bool IsConstantExpectedAttribute(INamedTypeSymbol namedType)
private abstract class ConstantExpectedParameter
{
- protected ConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax)
+ protected ConstantExpectedParameter(IParameterSymbol parameter)
{
Parameter = parameter;
- AttributeSyntax = attributeSyntax;
}
public IParameterSymbol Parameter { get; }
- public SyntaxNode AttributeSyntax { get; }
public abstract bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics);
- public abstract bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics);
+ public abstract bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, IArgumentOperation argument, [NotNullWhen(false)] out Diagnostic? validationDiagnostics);
}
private sealed class StringConstantExpectedParameter : ConstantExpectedParameter
{
- public StringConstantExpectedParameter(IParameterSymbol parameter, SyntaxNode attributeSyntax) : base(parameter, attributeSyntax) { }
+ public StringConstantExpectedParameter(IParameterSymbol parameter) : base(parameter) { }
- public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter subsetCandidate, IArgumentOperation argument, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
{
if (subsetCandidate is not StringConstantExpectedParameter)
{
- validationDiagnostics = Diagnostic.Create(AttributeNotSameTypeRule, subsetCandidate.AttributeSyntax.GetLocation(), Parameter.Type.ToDisplayString());
+ validationDiagnostics = Diagnostic.Create(CA1861.ConstantInvalidConstantRule, argument.Syntax.GetLocation(), Parameter.Type.ToDisplayString());
return false;
}
validationDiagnostics = null;
@@ -388,7 +362,7 @@ public override bool ValidateValue(IArgumentOperation argument, object? constant
{
if (constant is not string and not null)
{
- validationDiagnostics = argument.CreateDiagnostic(ConstantNotConstantRule);
+ validationDiagnostics = argument.CreateDiagnostic(CA1861.ConstantInvalidConstantRule, Parameter.Type.ToDisplayString());
return false;
}
validationDiagnostics = null;
@@ -397,32 +371,40 @@ public override bool ValidateValue(IArgumentOperation argument, object? constant
public static bool TryCreate(IParameterSymbol parameterSymbol, AttributeData attributeData, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
{
- if (!IsMinMaxValid(attributeData))
+ if (!IsMinMaxValid(attributeData, out _))
{
parameter = null;
return false;
}
- parameter = new StringConstantExpectedParameter(parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax());
+ parameter = new StringConstantExpectedParameter(parameterSymbol);
return true;
}
+ }
- public static bool Validate(AttributeData attributeData, out ImmutableArray diagnostics)
+ private static bool Validate(IParameterSymbol parameterSymbol, AttributeData attributeData, DiagnosticHelper helper, out ImmutableArray diagnostics)
+ {
+ if (!IsMinMaxValid(attributeData, out ErrorKind errorFlags))
{
- if (!IsMinMaxValid(attributeData))
- {
- diagnostics = ImmutableArray.Create(Diagnostic.Create(IncompatibleConstantForMinMaxRule, attributeData.ApplicationSyntaxReference.GetSyntax().GetLocation(), "string"));
- return false;
- }
- diagnostics = ImmutableArray.Empty;
- return true;
+ diagnostics = helper.GetError(errorFlags, parameterSymbol, attributeData.ApplicationSyntaxReference.GetSyntax(), "null", "null");
+ return false;
}
+ diagnostics = ImmutableArray.Empty;
+ return true;
+ }
- private static bool IsMinMaxValid(AttributeData attributeData)
+ private static bool IsMinMaxValid(AttributeData attributeData, out ErrorKind errorFlags)
+ {
+ (object? min, object? max) = GetAttributeConstants(attributeData);
+ errorFlags = 0;
+ if (min is not null)
{
- (object? min, object? max) = GetAttributeConstants(attributeData);
-
- return min is null && max is null;
+ errorFlags |= ErrorKind.MinIsIncompatible;
+ }
+ if (max is not null)
+ {
+ errorFlags |= ErrorKind.MaxIsIncompatible;
}
+ return min is null && max is null;
}
public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(AttributeData attributeData)
@@ -512,17 +494,17 @@ protected abstract class DiagnosticHelper
public abstract Location? GetMinLocation(SyntaxNode attributeSyntax);
public abstract Location? GetMaxLocation(SyntaxNode attributeSyntax);
- public ImmutableArray ParameterIsInvalid(string expectedTypeName, SyntaxNode attributeSyntax) => ImmutableArray.Create(Diagnostic.Create(InvalidTypeRule, attributeSyntax.GetLocation(), expectedTypeName));
+ public ImmutableArray ParameterIsInvalid(string expectedTypeName, SyntaxNode attributeSyntax) => ImmutableArray.Create(Diagnostic.Create(CA1860.UnsupportedTypeRule, attributeSyntax.GetLocation(), expectedTypeName));
- public Diagnostic MinIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(IncompatibleConstantTypeRule, GetMinLocation(attributeSyntax)!, "Min", expectedTypeName);
+ public Diagnostic MinIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMinLocation(attributeSyntax)!, "Min", expectedTypeName);
- public Diagnostic MaxIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(IncompatibleConstantTypeRule, GetMaxLocation(attributeSyntax)!, "Max", expectedTypeName);
+ public Diagnostic MaxIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMaxLocation(attributeSyntax)!, "Max", expectedTypeName);
- public Diagnostic MinIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(InvalidBoundsRule, GetMinLocation(attributeSyntax)!, "Min", typeMinValue, typeMaxValue);
+ public Diagnostic MinIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMinLocation(attributeSyntax)!, "Min", typeMinValue, typeMaxValue);
- public Diagnostic MaxIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(InvalidBoundsRule, GetMaxLocation(attributeSyntax)!, "Max", typeMinValue, typeMaxValue);
+ public Diagnostic MaxIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMaxLocation(attributeSyntax)!, "Max", typeMinValue, typeMaxValue);
- public static Diagnostic MinMaxIsInverted(SyntaxNode attributeSyntax) => Diagnostic.Create(InvertedRangeRule, attributeSyntax.GetLocation());
+ public static Diagnostic MinMaxIsInverted(SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.InvertedRangeRule, attributeSyntax.GetLocation());
public ImmutableArray GetError(ErrorKind errorFlags, IParameterSymbol parameterSymbol, SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue)
{
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 3bad61592f..21752dc7aa 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 3043ca61b9..9fa9e2078b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 764ca44e7a..25776cc285 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 f44c484e55..4ae1657667 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 661108a3aa..76f96c5150 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 2c9fcd7027..1848570953 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 d85ffb295c..67dada3a43 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 27e3742f8d..b30fa1dc22 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 a13dc83b3b..e075eb99a6 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
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 f4116a4e8d..7d8b633623 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 11f54868d1..07875dc005 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 0ec3d15e97..5d9e1eaf75 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
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
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 6eb98b0597..70ab89151f 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
@@ -197,54 +197,44 @@
The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
-
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
- The ConstantExpectedAttribute does not have the same '{0}' type as the ConstantExpectedAttribute in the invoked method parameter.
-
-
-
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
- The ConstantExpectedAttribute does not fit within the parameter value bounds of '{0}' to '{1}'.
-
-
-
- The Min/Max condition can only be null for '{0}' types.
- The Min/Max condition can only be null for '{0}' types.
-
-
- The '{0}' condition does not match parameter type of '{1}'.
- The '{0}' condition does not match parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' condition does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
-
- The '{0}' parameter cannot have be annotated with ConstantExpected.
- The '{0}' parameter cannot have be annotated with ConstantExpected.
+
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max conditions are inverted.
- The Min and Max conditions are inverted.
+ The Min and Max value are inverted.
+ The Min and Max value are inverted.
- The argument should be a constant.
- The argument should be a constant.
+ The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance.
+
+
+
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
- The constant does not fit within the parameter value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'.
- The parameter expects a constant for best performance.
- The parameter expects a constant for best performance.
+ The parameter expects a constant for optimal performance.
+ The parameter expects a constant for optimal performance.
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
index b65f0106c0..bc77277c42 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
@@ -1490,7 +1490,7 @@ ConstantExpectedAttribute is not applied correctly on the paramter.
## [CA1861](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861): Constant is expected for the parameter
-The parameter expects a constant for best performance.
+The parameter expects a constant for optimal performance.
|Item|Value|
|-|-|
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index 043b9c8b6a..5077e5db87 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -268,7 +268,7 @@
"CA1861": {
"id": "CA1861",
"shortDescription": "Constant is expected for the parameter",
- "fullDescription": "The parameter expects a constant for best performance.",
+ "fullDescription": "The parameter expects a constant for optimal performance.",
"defaultLevel": "warning",
"helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861",
"properties": {
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index ea6c42801e..28a110d4dd 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -24,6 +24,7 @@ public sealed class ConstantExpectedTests
[InlineData("uint", "uint.MinValue", "uint.MaxValue")]
[InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
[InlineData("nuint", "uint.MinValue", "uint.MaxValue")]
+ [InlineData("bool", "false", "true")]
[InlineData("float", "float.MinValue", "float.MaxValue")]
[InlineData("double", "double.MinValue", "double.MaxValue")]
public static async Task TestConstantExpectedSupportedUnmanagedTypesAsync(string type, string minValue, string maxValue)
@@ -35,27 +36,13 @@ public static async Task TestConstantExpectedSupportedUnmanagedTypesAsync(string
public class Test
{{
- public static void TestMethod1([ConstantExpected] {type} val)
- {{
- }}
- public static void TestMethod2([ConstantExpected(Min={minValue})] {type} val)
- {{
- }}
- public static void TestMethod3([ConstantExpected(Max={maxValue})] {type} val)
- {{
- }}
- public static void TestMethod4([ConstantExpected(Min={minValue}, Max={maxValue})] {type} val)
- {{
- }}
- public static void TestMethod5([ConstantExpected(Min=null)] {type} val)
- {{
- }}
- public static void TestMethod6([ConstantExpected(Max=null)] {type} val)
- {{
- }}
- public static void TestMethod7([ConstantExpected(Min=null, Max=null)] {type} val)
- {{
- }}
+ public static void TestMethod1([ConstantExpected] {type} val) {{ }}
+ public static void TestMethod2([ConstantExpected(Min={minValue})] {type} val) {{ }}
+ public static void TestMethod3([ConstantExpected(Max={maxValue})] {type} val) {{ }}
+ public static void TestMethod4([ConstantExpected(Min={minValue}, Max={maxValue})] {type} val) {{ }}
+ public static void TestMethod5([ConstantExpected(Min=null)] {type} val) {{ }}
+ public static void TestMethod6([ConstantExpected(Max=null)] {type} val) {{ }}
+ public static void TestMethod7([ConstantExpected(Min=null, Max=null)] {type} val) {{ }}
}}
";
await TestCSAsync(csInput);
@@ -71,18 +58,12 @@ public static async Task TestConstantExpectedSupportedComplexTypesAsync()
public class Test
{
- public static void TestMethodString([ConstantExpected] string val)
- {
- }
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
+ public static void TestMethodString([ConstantExpected] string val) { }
+ public static void TestMethodGeneric([ConstantExpected] T val) { }
public static class GenenricClass
{
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
+ public static void TestMethodGeneric([ConstantExpected] T val) { }
}
}
";
@@ -103,6 +84,7 @@ public static void TestMethodGeneric([ConstantExpected] T val)
[InlineData("nuint")]
[InlineData("float")]
[InlineData("double")]
+ [InlineData("bool")]
[InlineData("string")]
public static async Task TestConstantExpectedSupportedComplex2TypesAsync(string type)
{
@@ -135,11 +117,11 @@ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(0),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(1),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(2));
}
@@ -174,11 +156,11 @@ public class GenericForward : AbstractTest, ITest, ITest2
}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(0),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(1),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeExpectedRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.AttributeExpectedRule)
.WithLocation(2));
}
@@ -200,13 +182,11 @@ public static async Task TestConstantExpectedUnsupportedTypesAsync(string classG
public class Test{classGeneric}
{{
- public static void TestMethod{methodGeneric}([{{|#0:ConstantExpected|}}] {type} val)
- {{
- }}
+ public static void TestMethod{methodGeneric}([{{|#0:ConstantExpected|}}] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.UnsupportedTypeRule)
.WithLocation(0)
.WithArguments(diagnosticType));
}
@@ -251,91 +231,52 @@ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
}
[Theory]
- [InlineData("char", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("sbyte", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("short", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("int", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("long", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("nint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("byte", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("ushort", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("uint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("ulong", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("nuint", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("bool", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("float", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- [InlineData("double", "\"a\"", "\"a\"", "\"a\"", "\"a\"")]
- public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync(string type, string min1, string min2, string max2, string max3)
+ [InlineData("", "", "char", "\"a\"", "\"a\"")]
+ [InlineData("", "", "sbyte", "\"a\"", "\"a\"")]
+ [InlineData("", "", "short", "\"a\"", "\"a\"")]
+ [InlineData("", "", "int", "\"a\"", "\"a\"")]
+ [InlineData("", "", "long", "\"a\"", "\"a\"")]
+ [InlineData("", "", "nint", "\"a\"", "\"a\"")]
+ [InlineData("", "", "byte", "\"a\"", "\"a\"")]
+ [InlineData("", "", "ushort", "\"a\"", "\"a\"")]
+ [InlineData("", "", "uint", "\"a\"", "\"a\"")]
+ [InlineData("", "", "ulong", "\"a\"", "\"a\"")]
+ [InlineData("", "", "nuint", "\"a\"", "\"a\"")]
+ [InlineData("", "", "bool", "\"a\"", "\"a\"")]
+ [InlineData("", "", "float", "\"a\"", "\"a\"")]
+ [InlineData("", "", "double", "\"a\"", "\"a\"")]
+ [InlineData("", "", "string", "true", "false")]
+ [InlineData("", "", "T", "\"min\"", "false")]
+ [InlineData("", "", "T", "\"min\"", "false")]
+ public static async Task TestConstantExpectedIncompatibleConstantTypeErrorAsync(string classGeneric, string methodGeneric, string type, string badMinValue, string badMaxValue)
{
string csInput = @$"
using System;
using System.Diagnostics.CodeAnalysis;
#nullable enable
-public class Test
+public class Test{classGeneric}
{{
- public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] {type} val)
- {{
- }}
- public static void TestMethod2([ConstantExpected({{|#1:Min = {min2}|}}, {{|#2:Max = {max2}|}})] {type} val)
- {{
- }}
- public static void TestMethod3([ConstantExpected({{|#3:Max = {max3}|}})] {type} val)
- {{
- }}
+ public static void TestMethod{methodGeneric}([ConstantExpected({{|#0:Min = {badMinValue}|}})] {type} val) {{ }}
+ public static void TestMethod2{methodGeneric}([ConstantExpected({{|#1:Min = {badMinValue}|}}, {{|#2:Max = {badMaxValue}|}})] {type} val) {{ }}
+ public static void TestMethod3{methodGeneric}([ConstantExpected({{|#3:Max = {badMaxValue}|}})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(0)
.WithArguments("Min", type),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(1)
.WithArguments("Min", type),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(2)
.WithArguments("Max", type),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(3)
.WithArguments("Max", type));
}
- [Theory]
- [InlineData("", "", "string", "true", "false", "string")]
- [InlineData("", "", "T", "\"min\"", "false", "generic")]
- [InlineData("", "", "T", "\"min\"", "false", "generic")]
- public static async Task TestConstantExpectedIncompatibleConstantMinMaxTypeErrorAsync(string classGeneric, string methodGeneric, string type, string badMinValue, string badMaxValue, string diagnosticText)
- {
- string csInput = @$"
-using System;
-using System.Diagnostics.CodeAnalysis;
-#nullable enable
-
-public class Test{classGeneric}
-{{
- public static void TestMethod1{methodGeneric}([{{|#0:ConstantExpected(Min = {badMinValue})|}}] {type} val)
- {{
- }}
- public static void TestMethod2{methodGeneric}([{{|#1:ConstantExpected(Min = {badMinValue}, Max = {badMaxValue})|}}] {type} val)
- {{
- }}
- public static void TestMethod3{methodGeneric}([{{|#2:ConstantExpected(Max = {badMaxValue})|}}] {type} val)
- {{
- }}
-}}
-";
- await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(0)
- .WithArguments(diagnosticText),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(1)
- .WithArguments(diagnosticText),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantForMinMaxRule)
- .WithLocation(2)
- .WithArguments(diagnosticText));
- }
-
[Theory]
[InlineData("char", "'Z'", "'A'")]
[InlineData("sbyte", "1", "0")]
@@ -359,30 +300,27 @@ public static async Task TestConstantExpectedInvertedConstantTypeErrorAsync(stri
public class Test
{{
- public static void TestMethod([{{|#0:ConstantExpected(Min = {min}, Max = {max})|}}] {type} val)
- {{
- }}
+ public static void TestMethod([{{|#0:ConstantExpected(Min = {min}, Max = {max})|}}] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvertedRangeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvertedRangeRule)
.WithLocation(0));
}
[Theory]
- [InlineData("sbyte", sbyte.MinValue, sbyte.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("int", int.MinValue, int.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("long", long.MinValue, long.MaxValue, "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue", "ulong.MaxValue")]
- [InlineData("nint", int.MinValue, int.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("byte", byte.MinValue, byte.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("ushort", ushort.MinValue, ushort.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("uint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("ulong", ulong.MinValue, ulong.MaxValue, "long.MinValue", "long.MinValue", "-1", "-1")]
- [InlineData("nuint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MinValue", "long.MaxValue", "long.MaxValue")]
- [InlineData("float", float.MinValue, float.MaxValue, "double.MinValue", "double.MinValue", "double.MaxValue", "double.MaxValue")]
- public static async Task TestConstantExpectedInvalidBoundsAsync(string type, object min, object max, string min1, string min2, string max2,
- string max3)
+ [InlineData("sbyte", sbyte.MinValue, sbyte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("int", int.MinValue, int.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("long", long.MinValue, long.MaxValue, "ulong.MaxValue", "ulong.MaxValue", "false", "true")]
+ [InlineData("nint", int.MinValue, int.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("byte", byte.MinValue, byte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("ushort", ushort.MinValue, ushort.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("uint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("ulong", ulong.MinValue, ulong.MaxValue, "long.MinValue", "-1", "false", "true")]
+ [InlineData("nuint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("float", float.MinValue, float.MaxValue, "double.MinValue", "double.MaxValue", "false", "true")]
+ public static async Task TestConstantExpectedInvalidBoundsAsync(string type, object min, object max, string min1, string max1, string badMinValue, string badMaxValue)
{
string minString = min.ToString();
string maxString = max.ToString();
@@ -393,46 +331,36 @@ public static async Task TestConstantExpectedInvalidBoundsAsync(string type, obj
public class Test
{{
- public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] {type} val)
- {{
- }}
- public static void TestMethod2([ConstantExpected({{|#1:Min = {min2}|}}, {{|#2:Max = {max2}|}})] {type} val)
- {{
- }}
- public static void TestMethod3([ConstantExpected({{|#3:Max = {max3}|}})] {type} val)
- {{
- }}
- public static void TestMethod4([ConstantExpected({{|#4:Min = false|}}, {{|#5:Max = {max2}|}})] {type} val)
- {{
- }}
- public static void TestMethod5([ConstantExpected({{|#6:Min = {min2}|}}, {{|#7:Max = true|}})] {type} val)
- {{
- }}
+ public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] {type} val) {{ }}
+ public static void TestMethod2([ConstantExpected({{|#1:Min = {min1}|}}, {{|#2:Max = {max1}|}})] {type} val) {{ }}
+ public static void TestMethod3([ConstantExpected({{|#3:Max = {max1}|}})] {type} val) {{ }}
+ public static void TestMethod4([ConstantExpected({{|#4:Min = {badMinValue}|}}, {{|#5:Max = {max1}|}})] {type} val) {{ }}
+ public static void TestMethod5([ConstantExpected({{|#6:Min = {min1}|}}, {{|#7:Max = {badMaxValue}|}})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(0)
.WithArguments("Min", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(1)
.WithArguments("Min", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(2)
.WithArguments("Max", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(3)
.WithArguments("Max", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(4)
.WithArguments("Min", type),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(5)
.WithArguments("Max", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.InvalidBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
.WithLocation(6)
.WithArguments("Min", minString, maxString),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.IncompatibleConstantTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
.WithLocation(7)
.WithArguments("Max", type));
}
@@ -473,21 +401,13 @@ public static void TestMethod()
GenericClass<{type}>.TestMethodGeneric({value});
GenericClass<{type}>.TestMethodGeneric({expression});
}}
- public static void TestMethodWithConstant([ConstantExpected] {type} val)
- {{
- }}
- public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {minValue}, Max = {maxValue})] {type} val)
- {{
- }}
- public static void TestMethodGeneric([ConstantExpected] T val)
- {{
- }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val) {{ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {minValue}, Max = {maxValue})] {type} val) {{ }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
public static class GenericClass
{{
- public static void TestMethodGeneric([ConstantExpected] T val)
- {{
- }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
}}
}}
";
@@ -524,30 +444,63 @@ public static void TestMethod({type} nonConstant)
TestMethodGeneric<{type}>({{|#1:nonConstant|}});
GenenricClass<{type}>.TestMethodGeneric({{|#2:nonConstant|}});
}}
- public static void TestMethodWithConstant([ConstantExpected] {type} val)
- {{
- }}
- public static void TestMethodGeneric([ConstantExpected] T val)
- {{
- }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val) {{ }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
public static class GenenricClass
{{
- public static void TestMethodGeneric([ConstantExpected] T val)
- {{
- }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
}}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
.WithLocation(0),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
.WithLocation(1),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantNotConstantRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
.WithLocation(2));
}
+ [Theory]
+ [InlineData("char", "(char)(object)10.5")]
+ [InlineData("string", "(string)(object)20")]
+ public static async Task TestArgumentInvalidConstantAsync(string type, string constant)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod()
+ {{
+ TestMethodWithConstant({{|#0:{constant}|}});
+ TestMethodGeneric<{type}>({{|#1:{constant}|}});
+ GenericClass<{type}>.TestMethodGeneric({{|#2:{constant}|}});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val) {{ }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+
+ public static class GenericClass
+ {{
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+ }}
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
+ .WithLocation(0)
+ .WithArguments(type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
+ .WithLocation(1)
+ .WithArguments(type),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
+ .WithLocation(2)
+ .WithArguments(type));
+ }
+
[Theory]
[InlineData("char", "'B'", "'C'", "'D'")]
[InlineData("sbyte", "3", "4", "5")]
@@ -575,13 +528,11 @@ public static void TestMethod()
{{
TestMethodWithConstant({{|#0:{testValue}|}});
}}
- public static void TestMethodWithConstant([ConstantExpected(Min={min}, Max={max})] {type} val)
- {{
- }}
+ public static void TestMethodWithConstant([ConstantExpected(Min={min}, Max={max})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.ConstantOutOfBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantOutOfBoundsRule)
.WithLocation(0)
.WithArguments(min.Trim('\''), max.Trim('\'')));
}
@@ -599,17 +550,13 @@ public class Test
public static void TestMethod(int[] nonConstant)
{
TestMethodGeneric(nonConstant); // ignore scenario
- GenenricClass.TestMethodGeneric(nonConstant); // ignore scenario
- }
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
+ GenericClass.TestMethodGeneric(nonConstant); // ignore scenario
}
+ public static void TestMethodGeneric([ConstantExpected] T val) { }
- public static class GenenricClass
+ public static class GenericClass
{
- public static void TestMethodGeneric([ConstantExpected] T val)
- {
- }
+ public static void TestMethodGeneric([ConstantExpected] T val) { }
}
}
";
@@ -630,6 +577,7 @@ public static void TestMethodGeneric([ConstantExpected] T val)
[InlineData("nuint", "3", "4")]
[InlineData("float", "3", "4")]
[InlineData("double", "3", "4")]
+ [InlineData("bool", "false", "false")]
public static async Task TestConstantCompositionAsync(string type, string min, string max)
{
string csInput = @$"
@@ -643,17 +591,13 @@ public static void TestMethod([ConstantExpected] {type} constant)
{{
TestMethodWithConstant(constant);
}}
- public static void TestMethodWithConstant([ConstantExpected] {type} val)
- {{
- }}
+ public static void TestMethodWithConstant([ConstantExpected] {type} val) {{ }}
public static void TestMethodConstrained([ConstantExpected(Min = {min}, Max = {max})] {type} constant)
{{
TestMethodWithConstant(constant);
TestMethodWithConstrainedConstant(constant);
}}
- public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val)
- {{
- }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput);
@@ -673,29 +617,28 @@ public static void TestMethod([ConstantExpected] string constant)
{
TestMethodWithConstant(constant);
}
- public static void TestMethodWithConstant([ConstantExpected] string val)
- {
- }
+ public static void TestMethodWithConstant([ConstantExpected] string val) { }
}
";
await TestCSAsync(csInput);
}
[Theory]
- [InlineData("char", "'B'", "'C'", "'D'")]
- [InlineData("sbyte", "3", "4", "5")]
- [InlineData("short", "3", "4", "5")]
- [InlineData("int", "3", "4", "5")]
- [InlineData("long", "3", "4", "5")]
- [InlineData("nint", "3", "4", "5")]
- [InlineData("byte", "3", "4", "5")]
- [InlineData("ushort", "3", "4", "5")]
- [InlineData("uint", "3", "4", "5")]
- [InlineData("ulong", "3", "4", "5")]
- [InlineData("nuint", "3", "4", "5")]
- [InlineData("float", "3", "4", "5")]
- [InlineData("double", "3", "4", "5")]
- public static async Task TestConstantCompositionOutOfBoundsAsync(string type, string min, string max, string outOfBoundMax)
+ [InlineData("char", "'B'", "'C'", "'D'", 'B', 'C')]
+ [InlineData("sbyte", "3", "4", "5", 3, 4)]
+ [InlineData("short", "3", "4", "5", 3, 4)]
+ [InlineData("int", "3", "4", "5", 3, 4)]
+ [InlineData("long", "3", "4", "5", 3, 4)]
+ [InlineData("nint", "3", "4", "5", 3, 4)]
+ [InlineData("byte", "3", "4", "5", 3, 4)]
+ [InlineData("ushort", "3", "4", "5", 3, 4)]
+ [InlineData("uint", "3", "4", "5", 3, 4)]
+ [InlineData("ulong", "3", "4", "5", 3, 4)]
+ [InlineData("nuint", "3", "4", "5", 3, 4)]
+ [InlineData("float", "3", "4", "5", 3, 4)]
+ [InlineData("double", "3", "4", "5", 3, 4)]
+ [InlineData("bool", "false", "false", "true", false, false)]
+ public static async Task TestConstantCompositionOutOfBoundsAsync(string type, string min, string max, string outOfBoundMax, object minValue, object maxValue)
{
string csInput = @$"
using System;
@@ -704,19 +647,17 @@ public static async Task TestConstantCompositionOutOfBoundsAsync(string type, st
public class Test
{{
- public static void TestMethodConstrained([{{|#0:ConstantExpected(Min = {min}, Max = {outOfBoundMax})|}}] {type} constant)
- {{
- TestMethodWithConstrainedConstant(constant);
- }}
- public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val)
+ public static void TestMethodConstrained([ConstantExpected(Min = {min}, Max = {outOfBoundMax})] {type} constant)
{{
+ TestMethodWithConstrainedConstant({{|#0:constant|}});
}}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeOutOfBoundsRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantOutOfBoundsRule)
.WithLocation(0)
- .WithArguments(min.Trim('\''), max.Trim('\'')));
+ .WithArguments(minValue.ToString(), maxValue.ToString()));
}
[Fact]
@@ -729,25 +670,28 @@ public static async Task TestConstantCompositionNotSameTypeAsync()
public class Test
{
- public static void TestMethod([{|#0:ConstantExpected|}] long constant)
- {
- TestMethodWithConstant((int)constant);
- }
- public static void TestMethod([{|#1:ConstantExpected|}] short constant)
+ public static void TestMethod([ConstantExpected] long constant)
{
- TestMethodWithConstant(constant);
+ TestMethodWithConstant({|#0:(int)constant|});
+ TestMethodWithStringConstant({|#1:(string)(object)constant|});
}
- public static void TestMethodWithConstant([ConstantExpected] int val)
+ public static void TestMethod([ConstantExpected] short constant)
{
+ TestMethodWithConstant({|#2:constant|});
}
+ public static void TestMethodWithConstant([ConstantExpected] int val) { }
+ public static void TestMethodWithStringConstant([ConstantExpected] string val) { }
}
";
await TestCSAsync(csInput,
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeNotSameTypeRule)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
.WithLocation(0)
.WithArguments("int"),
- VerifyCS.Diagnostic(ConstantExpectedAnalyzer.AttributeNotSameTypeRule)
- .WithLocation(1)
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
+ .WithLocation(1)
+ .WithArguments("string"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantInvalidConstantRule)
+ .WithLocation(2)
.WithArguments("int"));
}
@@ -758,7 +702,7 @@ private static async Task TestCSAsync(string source, params DiagnosticResult[] d
TestCode = source,
LanguageVersion = CSharp.LanguageVersion.Preview,
};
- // TODO: remove when the type is avaiable
+ // TODO: remove when the type is available
test.TestState.Sources.Add(s_attributeSource);
test.ExpectedDiagnostics.AddRange(diagnosticResults);
await test.RunAsync();
From 7b883e0a86ecbd00de09079f2b9f6ba6c047e924 Mon Sep 17 00:00:00 2001
From: Wei Zheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 26 Feb 2022 07:29:59 +0800
Subject: [PATCH 08/27] Apply suggestions from code review
Co-authored-by: Robin Lindner
---
...ConstantExpectedAnalyzer.UnmanagedHelper.cs | 18 ++----------------
.../Performance/ConstantExpectedAnalyzer.cs | 3 ++-
2 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
index 93c3be961c..af1ee792e7 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
@@ -74,14 +74,7 @@ public bool TryTransformMin(object constant, out T value, ref ErrorKind errorFla
return true;
}
- if (isInvalid)
- {
- errorFlags |= ErrorKind.MinIsIncompatible;
- }
- else
- {
- errorFlags |= ErrorKind.MinIsOutOfRange;
- }
+ errorFlags |= isInvalid ? ErrorKind.MinIsIncompatible : ErrorKind.MinIsOutOfRange;
return false;
}
@@ -92,14 +85,7 @@ public bool TryTransformMax(object constant, out T value, ref ErrorKind errorFla
return true;
}
- if (isInvalid)
- {
- errorFlags |= ErrorKind.MaxIsIncompatible;
- }
- else
- {
- errorFlags |= ErrorKind.MaxIsOutOfRange;
- }
+ errorFlags |= isInvalid ? ErrorKind.MaxIsIncompatible : ErrorKind.MaxIsOutOfRange;
return false;
}
public bool TryConvert(object val, out T value) => _tryTransform(val, out value, out _);
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index bb75b25814..f4ed106415 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -134,6 +134,7 @@ private void OnCompilationStart(CompilationStartAnalysisContext context)
RegisterAttributeSyntax(context);
return;
}
+
private static void OnMethodSymbol(SymbolAnalysisContext context)
{
var methodSymbol = (IMethodSymbol)context.Symbol;
@@ -446,7 +447,7 @@ private static bool TryGetMethodInterface(IMethodSymbol methodSymbol, [NotNullWh
return true;
}
- if (methodSymbol.ContainingType != null)
+ if (methodSymbol.ContainingType is not null)
{
foreach (INamedTypeSymbol interfaceSymbol in methodSymbol.ContainingType.AllInterfaces)
{
From d12e2fb3c20f7fadede646eb2ddc7a3aba2c6a2e Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sun, 29 May 2022 08:05:05 +0800
Subject: [PATCH 09/27] Apply suggestion from feedback
---
.../Performance/CSharpConstantExpectedAnalyzer.cs | 6 +++---
.../Performance/ConstantExpectedAnalyzer.cs | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 5ae0754cef..fcc4079a28 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -13,8 +13,8 @@ namespace Microsoft.NetCore.CSharp.Analyzers.Performance
internal sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
{
private static readonly CSharpDiagnosticHelper s_diagnosticHelper = new();
- private readonly IdentifierNameSyntax _constantExpectedIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpected);
- private readonly IdentifierNameSyntax _constantExpectedAttributeIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedAttribute);
+ private static readonly IdentifierNameSyntax s_constantExpectedIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpected);
+ private static readonly IdentifierNameSyntax s_constantExpectedAttributeIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedAttribute);
protected override DiagnosticHelper Helper => s_diagnosticHelper;
@@ -25,7 +25,7 @@ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext
private void OnAttributeNode(SyntaxNodeAnalysisContext context)
{
var attributeSyntax = (AttributeSyntax)context.Node;
- if (!attributeSyntax.Name.IsEquivalentTo(_constantExpectedIdentifier) && !attributeSyntax.Name.IsEquivalentTo(_constantExpectedAttributeIdentifier))
+ if (!attributeSyntax.Name.IsEquivalentTo(s_constantExpectedIdentifier) && !attributeSyntax.Name.IsEquivalentTo(s_constantExpectedAttributeIdentifier))
{
return;
}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index f4ed106415..e14143bdac 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -159,6 +159,7 @@ static void CheckAttribute(SymbolAnalysisContext context, ImmutableArray
Date: Sat, 16 Jul 2022 20:16:31 +0800
Subject: [PATCH 10/27] Apply suggestions from code review
Co-authored-by: Robin Lindner
---
.../Performance/CSharpConstantExpectedAnalyzer.cs | 4 +++-
.../MicrosoftNetCoreAnalyzersResources.resx | 10 +++++-----
.../Performance/ConstantExpectedAnalyzer.cs | 1 -
.../Performance/ConstantExpectedTests.cs | 4 ++--
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index fcc4079a28..a0d40187c9 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -22,10 +22,12 @@ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext
{
context.RegisterSyntaxNodeAction(context => OnAttributeNode(context), SyntaxKind.Attribute);
}
+
private void OnAttributeNode(SyntaxNodeAnalysisContext context)
{
var attributeSyntax = (AttributeSyntax)context.Node;
- if (!attributeSyntax.Name.IsEquivalentTo(s_constantExpectedIdentifier) && !attributeSyntax.Name.IsEquivalentTo(s_constantExpectedAttributeIdentifier))
+ var attributeName = attributeSyntax.Name;
+ if (!attributeName.IsEquivalentTo(s_constantExpectedIdentifier) && !attributeName.IsEquivalentTo(s_constantExpectedAttributeIdentifier))
{
return;
}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index acfce126c1..d2838e2224 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1865,13 +1865,13 @@
'{0}' uses the preview type '{1}' and needs to opt into preview features. See {2} for more information.
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Constant is expected for the parameter
+ A constant is expected for the parameterThe parameter expects a constant for optimal performance.
@@ -1886,13 +1886,13 @@
The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.The argument should be a constant for optimal performance.
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index e14143bdac..ffd6c4eb3d 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -132,7 +132,6 @@ private void OnCompilationStart(CompilationStartAnalysisContext context)
context.RegisterOperationAction(OnInvocation, OperationKind.Invocation);
context.RegisterSymbolAction(context => OnMethodSymbol(context), SymbolKind.Method);
RegisterAttributeSyntax(context);
- return;
}
private static void OnMethodSymbol(SymbolAnalysisContext context)
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index 28a110d4dd..7ea86fd4fa 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -8,7 +8,7 @@
Microsoft.NetCore.CSharp.Analyzers.Performance.CSharpConstantExpectedAnalyzer,
Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>;
-namespace Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.Microsoft.NetCore.Analyzers.Performance
+namespace Microsoft.NetCore.Analyzers.Performance.UnitTests
{
public sealed class ConstantExpectedTests
{
@@ -528,7 +528,7 @@ public static void TestMethod()
{{
TestMethodWithConstant({{|#0:{testValue}|}});
}}
- public static void TestMethodWithConstant([ConstantExpected(Min={min}, Max={max})] {type} val) {{ }}
+ public static void TestMethodWithConstant([ConstantExpected(Min = {min}, Max = {max})] {type} val) {{ }}
}}
";
await TestCSAsync(csInput,
From 68e6e28056689c03b1e967ec66b778d4c975ff55 Mon Sep 17 00:00:00 2001
From: Wei Zheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 16 Jul 2022 20:19:44 +0800
Subject: [PATCH 11/27] Apply suggestions from code review
Co-authored-by: Buyaa Namnan
---
.../Performance/CSharpConstantExpectedAnalyzer.cs | 8 +++++---
.../MicrosoftNetCoreAnalyzersResources.resx | 4 ++--
.../Performance/ConstantExpectedAnalyzer.cs | 5 ++---
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index a0d40187c9..8712d2fb52 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -31,10 +31,12 @@ private void OnAttributeNode(SyntaxNodeAnalysisContext context)
{
return;
}
- var parameter = (ParameterSyntax)attributeSyntax.Parent.Parent;
- var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter);
- OnParameterWithConstantExpectedAttribute(parameterSymbol, context.ReportDiagnostic);
+ if (attributeSyntax.Parent.Parent is ParameterSyntax parameter)
+ {
+ var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter);
+ OnParameterWithConstantExpectedAttribute(parameterSymbol, context.ReportDiagnostic);
+ }
}
private sealed class CSharpDiagnosticHelper : DiagnosticHelper
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index d2838e2224..abdb3079b8 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1877,7 +1877,7 @@
The parameter expects a constant for optimal performance.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.The '{0}' value is not compatible with parameter type of '{1}'.
@@ -1898,7 +1898,7 @@
The argument should be a constant for optimal performance.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.Specify a culture or use an invariant version
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index ffd6c4eb3d..e549e157c1 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -311,10 +311,9 @@ private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol,
private static bool TryGetConstantExpectedAttributeData(IParameterSymbol parameter, [NotNullWhen(true)] out AttributeData? attributeData)
{
- AttributeData? constantExpectedAttributeData = parameter.GetAttributes()
+ attributeData = parameter.GetAttributes()
.FirstOrDefault(attrData => IsConstantExpectedAttribute(attrData.AttributeClass));
- attributeData = constantExpectedAttributeData;
- return constantExpectedAttributeData is not null;
+ return attributeData is not null;
}
private static bool HasConstantExpectedAttributeData(IParameterSymbol parameter)
From 52f5e3ffeaf4bd5cbd905cecf06dd0ae3eeef23c Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 16 Jul 2022 20:39:59 +0800
Subject: [PATCH 12/27] rebuild
---
.../MicrosoftNetCoreAnalyzersResources.cs.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.de.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.es.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.fr.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.it.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ja.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ko.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.pl.xlf | 28 +++++++++----------
...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ru.xlf | 28 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.tr.xlf | 28 +++++++++----------
...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 28 +++++++++----------
...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 28 +++++++++----------
.../Microsoft.CodeAnalysis.NetAnalyzers.md | 6 ++--
.../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 6 ++--
src/NetAnalyzers/RulesMissingDocumentation.md | 4 +--
.../Performance/ConstantExpectedTests.cs | 2 +-
17 files changed, 191 insertions(+), 191 deletions(-)
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 68e86fc868..803eef53ea 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 a77a8d100e..db7fe0a9ff 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 c45163d770..43490fa1d9 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 4a4bbcf756..187dbf6d4b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 ba3db53d0b..f386d11df4 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 a86d8771de..625e2b6ba2 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 4e9e708797..c27c9e0b6b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 26f795ee95..b2f7c27e7c 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 0bd9ad7fa1..d6fcd69750 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
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 5416ab1480..c9922900d5 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 82244a72d9..b3ec8caece 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 6bbc7f8cc3..55cbbc4ec5 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
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
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 5a8de23ff9..624e9fd873 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
@@ -183,18 +183,18 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the paramter.
- ConstantExpectedAttribute is not applied correctly on the paramter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpectedAttribute is not applied correctly on the parameter.
- Incorrect use of ConstantExpectedAttribute
- Incorrect use of ConstantExpectedAttribute
+ Incorrect usage of ConstantExpected attribute
+ Incorrect usage of ConstantExpected attribute
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
- The ConstantExpectedAttribute expected for the parameter due to the interface/base method.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation.
@@ -208,13 +208,13 @@
- The constant is not of the same '{0}' type as the parameter
- The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter.
- The Min and Max value are inverted.
- The Min and Max value are inverted.
+ The Min and Max values are inverted.
+ The Min and Max values are inverted.
@@ -223,8 +223,8 @@
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
- The '{0}' parameter is not supported for ConstantExpectedAttribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute.
@@ -238,8 +238,8 @@
- Constant is expected for the parameter
- Constant is expected for the parameter
+ A constant is expected for the parameter
+ A constant is expected for the parameter
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
index ee79360ecd..84ef4e0b73 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
@@ -1560,9 +1560,9 @@ Prefer a 'TryGetValue' call over a Dictionary indexer access guarded by a 'Conta
|CodeFix|True|
---
-## [CA1860](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860): Incorrect use of ConstantExpectedAttribute
+## [CA1860](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860): Incorrect usage of ConstantExpected attribute
-ConstantExpectedAttribute is not applied correctly on the paramter.
+ConstantExpectedAttribute is not applied correctly on the parameter.
|Item|Value|
|-|-|
@@ -1572,7 +1572,7 @@ ConstantExpectedAttribute is not applied correctly on the paramter.
|CodeFix|False|
---
-## [CA1861](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861): Constant is expected for the parameter
+## [CA1861](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861): A constant is expected for the parameter
The parameter expects a constant for optimal performance.
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index eef6f54f1e..10d49e57b5 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -287,8 +287,8 @@
},
"CA1860": {
"id": "CA1860",
- "shortDescription": "Incorrect use of ConstantExpectedAttribute",
- "fullDescription": "ConstantExpectedAttribute is not applied correctly on the paramter.",
+ "shortDescription": "Incorrect usage of ConstantExpected attribute",
+ "fullDescription": "ConstantExpectedAttribute is not applied correctly on the parameter.",
"defaultLevel": "error",
"helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1860",
"properties": {
@@ -306,7 +306,7 @@
},
"CA1861": {
"id": "CA1861",
- "shortDescription": "Constant is expected for the parameter",
+ "shortDescription": "A constant is expected for the parameter",
"fullDescription": "The parameter expects a constant for optimal performance.",
"defaultLevel": "warning",
"helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861",
diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md
index f55d144721..b9bca791bd 100644
--- a/src/NetAnalyzers/RulesMissingDocumentation.md
+++ b/src/NetAnalyzers/RulesMissingDocumentation.md
@@ -7,7 +7,7 @@ CA1420 | | This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied |
CA1852 | | Seal internal types |
CA1853 | | Unnecessary call to 'Dictionary.ContainsKey(key)' |
-CA1860 | | Incorrect use of ConstantExpectedAttribute |
-CA1861 | | Constant is expected for the parameter |
+CA1860 | | Incorrect usage of ConstantExpected attribute |
+CA1861 | | A constant is expected for the parameter |
CA2019 | | Improper 'ThreadStatic' field initialization |
CA2259 | | 'ThreadStatic' only affects static fields |
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index 7ea86fd4fa..d35e8d0e79 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -700,7 +700,7 @@ private static async Task TestCSAsync(string source, params DiagnosticResult[] d
var test = new VerifyCS.Test
{
TestCode = source,
- LanguageVersion = CSharp.LanguageVersion.Preview,
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.Preview,
};
// TODO: remove when the type is available
test.TestState.Sources.Add(s_attributeSource);
From f991607ee27fe080732231fda413b30c81b59314 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 16 Jul 2022 20:40:03 +0800
Subject: [PATCH 13/27] Use const variable for Min Max literal
---
.../CSharpConstantExpectedAnalyzer.cs | 4 ++--
.../Performance/ConstantExpectedAnalyzer.cs | 18 ++++++++++--------
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 8712d2fb52..462e9e3990 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -41,8 +41,8 @@ private void OnAttributeNode(SyntaxNodeAnalysisContext context)
private sealed class CSharpDiagnosticHelper : DiagnosticHelper
{
- private readonly IdentifierNameSyntax _constantExpectedMinIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName("Min");
- private readonly IdentifierNameSyntax _constantExpectedMaxIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName("Max");
+ private readonly IdentifierNameSyntax _constantExpectedMinIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedMin);
+ private readonly IdentifierNameSyntax _constantExpectedMaxIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpectedMax);
public override Location? GetMaxLocation(SyntaxNode attributeNode) => GetArgumentLocation(attributeNode, _constantExpectedMaxIdentifier);
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index e549e157c1..656a7ac5aa 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -17,6 +17,8 @@ public abstract partial class ConstantExpectedAnalyzer : DiagnosticAnalyzer
{
protected static readonly string ConstantExpectedAttribute = nameof(ConstantExpectedAttribute);
protected static readonly string ConstantExpected = nameof(ConstantExpected);
+ protected const string ConstantExpectedMin = "Min";
+ protected const string ConstantExpectedMax = "Max";
private static readonly LocalizableString s_localizableApplicationTitle = CreateLocalizableResourceString(nameof(ConstantExpectedApplicationTitle));
private static readonly LocalizableString s_localizableApplicationDescription = CreateLocalizableResourceString(nameof(ConstantExpectedApplicationDescription));
private static readonly LocalizableString s_localizableUsageTitle = CreateLocalizableResourceString(nameof(ConstantExpectedUsageTitle));
@@ -326,8 +328,8 @@ private static bool IsConstantExpectedAttribute(INamedTypeSymbol namedType)
{
return namedType.Name.Equals(ConstantExpectedAttribute, StringComparison.Ordinal) &&
namedType.GetMembers().OfType()
- .All(s => s.Name.Equals("Min", StringComparison.Ordinal) ||
- s.Name.Equals("Max", StringComparison.Ordinal));
+ .All(s => s.Name.Equals(ConstantExpectedMin, StringComparison.Ordinal) ||
+ s.Name.Equals(ConstantExpectedMax, StringComparison.Ordinal));
}
private abstract class ConstantExpectedParameter
@@ -414,11 +416,11 @@ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(A
foreach (var namedArg in attributeData.NamedArguments)
{
- if (namedArg.Key.Equals("Min", StringComparison.Ordinal))
+ if (namedArg.Key.Equals(ConstantExpectedMin, StringComparison.Ordinal))
{
minConstant = ToObject(namedArg.Value);
}
- else if (namedArg.Key.Equals("Max", StringComparison.Ordinal))
+ else if (namedArg.Key.Equals(ConstantExpectedMax, StringComparison.Ordinal))
{
maxConstant = ToObject(namedArg.Value);
}
@@ -496,13 +498,13 @@ protected abstract class DiagnosticHelper
public ImmutableArray ParameterIsInvalid(string expectedTypeName, SyntaxNode attributeSyntax) => ImmutableArray.Create(Diagnostic.Create(CA1860.UnsupportedTypeRule, attributeSyntax.GetLocation(), expectedTypeName));
- public Diagnostic MinIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMinLocation(attributeSyntax)!, "Min", expectedTypeName);
+ public Diagnostic MinIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMinLocation(attributeSyntax)!, ConstantExpectedMin, expectedTypeName);
- public Diagnostic MaxIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMaxLocation(attributeSyntax)!, "Max", expectedTypeName);
+ public Diagnostic MaxIsIncompatible(string expectedTypeName, SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.IncompatibleConstantTypeRule, GetMaxLocation(attributeSyntax)!, ConstantExpectedMax, expectedTypeName);
- public Diagnostic MinIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMinLocation(attributeSyntax)!, "Min", typeMinValue, typeMaxValue);
+ public Diagnostic MinIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMinLocation(attributeSyntax)!, ConstantExpectedMin, typeMinValue, typeMaxValue);
- public Diagnostic MaxIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMaxLocation(attributeSyntax)!, "Max", typeMinValue, typeMaxValue);
+ public Diagnostic MaxIsOutOfRange(SyntaxNode attributeSyntax, string typeMinValue, string typeMaxValue) => Diagnostic.Create(CA1860.InvalidBoundsRule, GetMaxLocation(attributeSyntax)!, ConstantExpectedMax, typeMinValue, typeMaxValue);
public static Diagnostic MinMaxIsInverted(SyntaxNode attributeSyntax) => Diagnostic.Create(CA1860.InvertedRangeRule, attributeSyntax.GetLocation());
From eab469f0bb0ee0990233008b8d78640fae2bb7b9 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 16 Jul 2022 20:51:44 +0800
Subject: [PATCH 14/27] Drop nint nuint support from ConstantExpected
---
.../CSharpConstantExpectedAnalyzer.cs | 2 +-
.../Performance/ConstantExpectedAnalyzer.cs | 10 --------
.../Performance/ConstantExpectedTests.cs | 23 ++-----------------
3 files changed, 3 insertions(+), 32 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 462e9e3990..7c68c609b4 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -22,7 +22,7 @@ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext
{
context.RegisterSyntaxNodeAction(context => OnAttributeNode(context), SyntaxKind.Attribute);
}
-
+
private void OnAttributeNode(SyntaxNodeAnalysisContext context)
{
var attributeSyntax = (AttributeSyntax)context.Node;
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index 656a7ac5aa..75fd387ba8 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -237,8 +237,6 @@ private static bool TryCreateConstantExpectedParameter(IParameterSymbol paramete
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, out parameter);
case SpecialType.System_UInt64:
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, ulong.MinValue, ulong.MaxValue, out parameter);
- case SpecialType.System_UIntPtr:
- return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, out parameter);
case SpecialType.System_SByte:
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, sbyte.MinValue, sbyte.MaxValue, out parameter);
case SpecialType.System_Int16:
@@ -247,8 +245,6 @@ private static bool TryCreateConstantExpectedParameter(IParameterSymbol paramete
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, out parameter);
case SpecialType.System_Int64:
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, long.MinValue, long.MaxValue, out parameter);
- case SpecialType.System_IntPtr:
- return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, out parameter);
case SpecialType.System_Single:
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, float.MinValue, float.MaxValue, out parameter);
case SpecialType.System_Double:
@@ -283,8 +279,6 @@ private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol,
return UnmanagedHelper.Validate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, Helper, out diagnostics);
case SpecialType.System_UInt64:
return UnmanagedHelper.Validate(parameterSymbol, attributeData, ulong.MinValue, ulong.MaxValue, Helper, out diagnostics);
- case SpecialType.System_UIntPtr:
- return UnmanagedHelper.Validate(parameterSymbol, attributeData, uint.MinValue, uint.MaxValue, Helper, out diagnostics);
case SpecialType.System_SByte:
return UnmanagedHelper.Validate(parameterSymbol, attributeData, sbyte.MinValue, sbyte.MaxValue, Helper, out diagnostics);
case SpecialType.System_Int16:
@@ -293,8 +287,6 @@ private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol,
return UnmanagedHelper.Validate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, Helper, out diagnostics);
case SpecialType.System_Int64:
return UnmanagedHelper.Validate(parameterSymbol, attributeData, long.MinValue, long.MaxValue, Helper, out diagnostics);
- case SpecialType.System_IntPtr:
- return UnmanagedHelper.Validate(parameterSymbol, attributeData, int.MinValue, int.MaxValue, Helper, out diagnostics);
case SpecialType.System_Single:
return UnmanagedHelper.Validate(parameterSymbol, attributeData, float.MinValue, float.MaxValue, Helper, out diagnostics);
case SpecialType.System_Double:
@@ -476,12 +468,10 @@ private static bool IsConstantCompatible(ITypeSymbol type)
SpecialType.System_UInt16 => true,
SpecialType.System_UInt32 => true,
SpecialType.System_UInt64 => true,
- SpecialType.System_UIntPtr => true,
SpecialType.System_SByte => true,
SpecialType.System_Int16 => true,
SpecialType.System_Int32 => true,
SpecialType.System_Int64 => true,
- SpecialType.System_IntPtr => true,
SpecialType.System_Single => true,
SpecialType.System_Double => true,
SpecialType.System_Boolean => true,
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index d35e8d0e79..da2b0c4413 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -2,7 +2,6 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
-using Microsoft.NetCore.Analyzers.Performance;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
Microsoft.NetCore.CSharp.Analyzers.Performance.CSharpConstantExpectedAnalyzer,
@@ -18,12 +17,10 @@ public sealed class ConstantExpectedTests
[InlineData("short", "short.MinValue", "short.MaxValue")]
[InlineData("int", "int.MinValue", "int.MaxValue")]
[InlineData("long", "long.MinValue", "long.MaxValue")]
- [InlineData("nint", "int.MinValue", "int.MaxValue")]
[InlineData("byte", "byte.MinValue", "byte.MaxValue")]
[InlineData("ushort", "ushort.MinValue", "ushort.MaxValue")]
[InlineData("uint", "uint.MinValue", "uint.MaxValue")]
[InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
- [InlineData("nuint", "uint.MinValue", "uint.MaxValue")]
[InlineData("bool", "false", "true")]
[InlineData("float", "float.MinValue", "float.MaxValue")]
[InlineData("double", "double.MinValue", "double.MaxValue")]
@@ -76,12 +73,10 @@ public static void TestMethodGeneric([ConstantExpected] T val) { }
[InlineData("short")]
[InlineData("int")]
[InlineData("long")]
- [InlineData("nint")]
[InlineData("byte")]
[InlineData("ushort")]
[InlineData("uint")]
[InlineData("ulong")]
- [InlineData("nuint")]
[InlineData("float")]
[InlineData("double")]
[InlineData("bool")]
@@ -165,6 +160,8 @@ await TestCSAsync(csInput,
}
[Theory]
+ [InlineData("", "", "nint", "nint")]
+ [InlineData("", "", "nuint", "nuint")]
[InlineData("", "", "object", "object")]
[InlineData("", "", "Test", "Test")]
[InlineData("", "", "Guid", "System.Guid")]
@@ -236,12 +233,10 @@ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
[InlineData("", "", "short", "\"a\"", "\"a\"")]
[InlineData("", "", "int", "\"a\"", "\"a\"")]
[InlineData("", "", "long", "\"a\"", "\"a\"")]
- [InlineData("", "", "nint", "\"a\"", "\"a\"")]
[InlineData("", "", "byte", "\"a\"", "\"a\"")]
[InlineData("", "", "ushort", "\"a\"", "\"a\"")]
[InlineData("", "", "uint", "\"a\"", "\"a\"")]
[InlineData("", "", "ulong", "\"a\"", "\"a\"")]
- [InlineData("", "", "nuint", "\"a\"", "\"a\"")]
[InlineData("", "", "bool", "\"a\"", "\"a\"")]
[InlineData("", "", "float", "\"a\"", "\"a\"")]
[InlineData("", "", "double", "\"a\"", "\"a\"")]
@@ -283,12 +278,10 @@ await TestCSAsync(csInput,
[InlineData("short", "1", "0")]
[InlineData("int", "1", "0")]
[InlineData("long", "1", "0")]
- [InlineData("nint", "1", "0")]
[InlineData("byte", "1", "0")]
[InlineData("ushort", "1", "0")]
[InlineData("uint", "1", "0")]
[InlineData("ulong", "1", "0")]
- [InlineData("nuint", "1", "0")]
[InlineData("float", "1", "0")]
[InlineData("double", "1", "0")]
public static async Task TestConstantExpectedInvertedConstantTypeErrorAsync(string type, string min, string max)
@@ -313,12 +306,10 @@ await TestCSAsync(csInput,
[InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("int", int.MinValue, int.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("long", long.MinValue, long.MaxValue, "ulong.MaxValue", "ulong.MaxValue", "false", "true")]
- [InlineData("nint", int.MinValue, int.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("byte", byte.MinValue, byte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("ushort", ushort.MinValue, ushort.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("uint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("ulong", ulong.MinValue, ulong.MaxValue, "long.MinValue", "-1", "false", "true")]
- [InlineData("nuint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("float", float.MinValue, float.MaxValue, "double.MinValue", "double.MaxValue", "false", "true")]
public static async Task TestConstantExpectedInvalidBoundsAsync(string type, object min, object max, string min1, string max1, string badMinValue, string badMaxValue)
{
@@ -371,12 +362,10 @@ await TestCSAsync(csInput,
[InlineData("short", "10", "20", "10", "2*5")]
[InlineData("int", "10", "20", "10", "2*5")]
[InlineData("long", "10", "20", "10", "2*5")]
- [InlineData("nint", "10", "20", "10", "2*5")]
[InlineData("byte", "10", "20", "10", "2*5")]
[InlineData("ushort", "10", "20", "10", "2*5")]
[InlineData("uint", "10", "20", "10", "2*5")]
[InlineData("ulong", "10", "20", "10", "2*5")]
- [InlineData("nuint", "10", "20", "10", "2*5")]
[InlineData("float", "10", "20", "10", "2*5")]
[InlineData("double", "10", "20", "10", "2*5")]
[InlineData("bool", "true", "true", "true", "!false")]
@@ -420,12 +409,10 @@ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
[InlineData("short")]
[InlineData("int")]
[InlineData("long")]
- [InlineData("nint")]
[InlineData("byte")]
[InlineData("ushort")]
[InlineData("uint")]
[InlineData("ulong")]
- [InlineData("nuint")]
[InlineData("float")]
[InlineData("double")]
[InlineData("string")]
@@ -507,12 +494,10 @@ await TestCSAsync(csInput,
[InlineData("short", "3", "4", "5")]
[InlineData("int", "3", "4", "5")]
[InlineData("long", "3", "4", "5")]
- [InlineData("nint", "3", "4", "5")]
[InlineData("byte", "3", "4", "5")]
[InlineData("ushort", "3", "4", "5")]
[InlineData("uint", "3", "4", "5")]
[InlineData("ulong", "3", "4", "5")]
- [InlineData("nuint", "3", "4", "5")]
[InlineData("float", "3", "4", "5")]
[InlineData("double", "3", "4", "5")]
public static async Task TestArgumentOutOfBoundsConstantAsync(string type, string min, string max, string testValue)
@@ -569,12 +554,10 @@ public static void TestMethodGeneric([ConstantExpected] T val) { }
[InlineData("short", "3", "4")]
[InlineData("int", "3", "4")]
[InlineData("long", "3", "4")]
- [InlineData("nint", "3", "4")]
[InlineData("byte", "3", "4")]
[InlineData("ushort", "3", "4")]
[InlineData("uint", "3", "4")]
[InlineData("ulong", "3", "4")]
- [InlineData("nuint", "3", "4")]
[InlineData("float", "3", "4")]
[InlineData("double", "3", "4")]
[InlineData("bool", "false", "false")]
@@ -629,12 +612,10 @@ public static void TestMethodWithConstant([ConstantExpected] string val) { }
[InlineData("short", "3", "4", "5", 3, 4)]
[InlineData("int", "3", "4", "5", 3, 4)]
[InlineData("long", "3", "4", "5", 3, 4)]
- [InlineData("nint", "3", "4", "5", 3, 4)]
[InlineData("byte", "3", "4", "5", 3, 4)]
[InlineData("ushort", "3", "4", "5", 3, 4)]
[InlineData("uint", "3", "4", "5", 3, 4)]
[InlineData("ulong", "3", "4", "5", 3, 4)]
- [InlineData("nuint", "3", "4", "5", 3, 4)]
[InlineData("float", "3", "4", "5", 3, 4)]
[InlineData("double", "3", "4", "5", 3, 4)]
[InlineData("bool", "false", "false", "true", false, false)]
From 5e1b4c35baa6e90c8519f25e98d366969764d2da Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 16 Jul 2022 21:35:15 +0800
Subject: [PATCH 15/27] Add early exit if symbol for attribute is not found
---
.../Performance/ConstantExpectedAnalyzer.cs | 4 ++
.../Performance/ConstantExpectedTests.cs | 72 +++++++++++++++++++
src/Utilities/Compiler/WellKnownTypeNames.cs | 1 +
3 files changed, 77 insertions(+)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index 75fd387ba8..c12acf0d60 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -131,6 +131,10 @@ public override void Initialize(AnalysisContext context)
private void OnCompilationStart(CompilationStartAnalysisContext context)
{
+ if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDiagnosticsCodeAnalysisConstantExpectedAttribute, out _))
+ {
+ return;
+ }
context.RegisterOperationAction(OnInvocation, OperationKind.Invocation);
context.RegisterSymbolAction(context => OnMethodSymbol(context), SymbolKind.Method);
RegisterAttributeSyntax(context);
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index da2b0c4413..9947c2062b 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -120,6 +120,53 @@ await TestCSAsync(csInput,
.WithLocation(2));
}
+ [Theory]
+ [InlineData("char")]
+ [InlineData("sbyte")]
+ [InlineData("short")]
+ [InlineData("int")]
+ [InlineData("long")]
+ [InlineData("byte")]
+ [InlineData("ushort")]
+ [InlineData("uint")]
+ [InlineData("ulong")]
+ [InlineData("float")]
+ [InlineData("double")]
+ [InlineData("bool")]
+ [InlineData("string")]
+ public static async Task TestMissingConstantExpectedSupportedComplex2TypesAsync(string type)
+ {
+ string csInput = @$"
+using System;
+using Similar;
+#nullable enable
+
+public class Test
+{{
+ public interface ITest
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public interface ITest2
+ {{
+ T Method(T operand1, [ConstantExpected] T operand2);
+ }}
+ public abstract class AbstractTest
+ {{
+ public abstract T Method2(T operand1, [ConstantExpected] T operand2);
+ }}
+
+ public class Generic : AbstractTest<{type}>, ITest<{type}>, ITest2<{type}>
+ {{
+ public {type} Method({type} operand1, {type} operand2) => throw new NotImplementedException();
+ {type} ITest2<{type}>.Method({type} operand1, {type} operand2) => throw new NotImplementedException();
+ public override {type} Method2({type} operand1, {type} operand2) => throw new NotImplementedException();
+ }}
+}}
+";
+ await TestCSMissingAttributeAsync(csInput);
+ }
+
[Fact]
public static async Task TestConstantExpectedSupportedComplex3TypesAsync()
{
@@ -691,6 +738,31 @@ private static async Task TestCSAsync(string source, params DiagnosticResult[] d
private static readonly string s_attributeSource = @"#nullable enable
namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
+ public sealed class ConstantExpectedAttribute : Attribute
+ {
+ public object? Min { get; set; }
+ public object? Max { get; set; }
+ }
+}";
+
+ private static async Task TestCSMissingAttributeAsync(string source, params DiagnosticResult[] diagnosticResults)
+ {
+ var test = new VerifyCS.Test
+ {
+ TestCode = source,
+ ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
+ LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.Preview,
+ };
+ test.TestState.Sources.Add(s_similarAttributeSource);
+ test.ExpectedDiagnostics.AddRange(diagnosticResults);
+ await test.RunAsync();
+ }
+
+ private static readonly string s_similarAttributeSource = @"#nullable enable
+using System;
+namespace Similar
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public sealed class ConstantExpectedAttribute : Attribute
diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs
index 327993b3d4..9440003764 100644
--- a/src/Utilities/Compiler/WellKnownTypeNames.cs
+++ b/src/Utilities/Compiler/WellKnownTypeNames.cs
@@ -196,6 +196,7 @@ internal static class WellKnownTypeNames
public const string SystemDateTimeOffset = "System.DateTimeOffset";
public const string SystemDecimal = "System.Decimal";
public const string SystemDiagnosticContractsContract = "System.Diagnostics.Contracts.Contract";
+ public const string SystemDiagnosticsCodeAnalysisConstantExpectedAttribute = "System.Diagnostics.CodeAnalysis.ConstantExpectedAttribute";
public const string SystemDiagnosticsCodeAnalysisNotNullAttribute = "System.Diagnostics.CodeAnalysis.NotNullAttribute";
public const string SystemDiagnosticsConditionalAttribute = "System.Diagnostics.ConditionalAttribute";
public const string SystemDiagnosticsContractsPureAttribute = "System.Diagnostics.Contracts.PureAttribute";
From e7ac7928b43bd94325de7c6a4e5fe3a7879b1d97 Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 23 Jul 2022 20:27:12 +0800
Subject: [PATCH 16/27] Add check for enums
---
.../Performance/ConstantExpectedAnalyzer.cs | 24 +-
.../Performance/ConstantExpectedTests.cs | 362 ++++++++++++++++++
2 files changed, 384 insertions(+), 2 deletions(-)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index c12acf0d60..91715c0a82 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -223,13 +223,15 @@ protected void OnParameterWithConstantExpectedAttribute(IParameterSymbol paramet
private static bool TryCreateConstantExpectedParameter(IParameterSymbol parameterSymbol, [NotNullWhen(true)] out ConstantExpectedParameter? parameter)
{
+ var underlyingType = GetUnderlyingType(parameterSymbol);
+
if (!TryGetConstantExpectedAttributeData(parameterSymbol, out var attributeData))
{
parameter = null;
return false;
}
- switch (parameterSymbol.Type.SpecialType)
+ switch (underlyingType.SpecialType)
{
case SpecialType.System_Char:
return UnmanagedHelper.TryCreate(parameterSymbol, attributeData, char.MinValue, char.MaxValue, out parameter);
@@ -265,13 +267,15 @@ private static bool TryCreateConstantExpectedParameter(IParameterSymbol paramete
private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol, out ImmutableArray diagnostics)
{
+ var underlyingType = GetUnderlyingType(parameterSymbol);
+
if (!TryGetConstantExpectedAttributeData(parameterSymbol, out var attributeData))
{
diagnostics = ImmutableArray.Empty;
return false;
}
- switch (parameterSymbol.Type.SpecialType)
+ switch (underlyingType.SpecialType)
{
case SpecialType.System_Char:
return UnmanagedHelper.Validate(parameterSymbol, attributeData, char.MinValue, char.MaxValue, Helper, out diagnostics);
@@ -307,6 +311,22 @@ private bool ValidateConstantExpectedParameter(IParameterSymbol parameterSymbol,
}
}
+ private static ITypeSymbol GetUnderlyingType(IParameterSymbol parameterSymbol)
+ {
+ ITypeSymbol underlyingType;
+ if (parameterSymbol.Type.TypeKind is TypeKind.Enum)
+ {
+ var enumType = (INamedTypeSymbol)parameterSymbol.Type;
+ underlyingType = enumType.EnumUnderlyingType;
+ }
+ else
+ {
+ underlyingType = parameterSymbol.Type;
+ }
+
+ return underlyingType;
+ }
+
private static bool TryGetConstantExpectedAttributeData(IParameterSymbol parameter, [NotNullWhen(true)] out AttributeData? attributeData)
{
attributeData = parameter.GetAttributes()
diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
index 9947c2062b..347811b6e8 100644
--- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
+++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedTests.cs
@@ -45,6 +45,42 @@ public static void TestMethod7([ConstantExpected(Min=null, Max=null)] {type} val
await TestCSAsync(csInput);
}
+ [Theory]
+ [InlineData("sbyte", "sbyte.MinValue", "sbyte.MaxValue")]
+ [InlineData("short", "short.MinValue", "short.MaxValue")]
+ [InlineData("int", "int.MinValue", "int.MaxValue")]
+ [InlineData("long", "long.MinValue", "long.MaxValue")]
+ [InlineData("byte", "byte.MinValue", "byte.MaxValue")]
+ [InlineData("ushort", "ushort.MinValue", "ushort.MaxValue")]
+ [InlineData("uint", "uint.MinValue", "uint.MaxValue")]
+ [InlineData("ulong", "ulong.MinValue", "ulong.MaxValue")]
+ public static async Task TestConstantExpectedSupportedEnumTypesAsync(string type, string minValue, string maxValue)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod1([ConstantExpected] AEnum val) {{ }}
+ public static void TestMethod2([ConstantExpected(Min={minValue})] AEnum val) {{ }}
+ public static void TestMethod3([ConstantExpected(Max={maxValue})] AEnum val) {{ }}
+ public static void TestMethod4([ConstantExpected(Min={minValue}, Max={maxValue})] AEnum val) {{ }}
+ public static void TestMethod5([ConstantExpected(Min=null)] AEnum val) {{ }}
+ public static void TestMethod6([ConstantExpected(Max=null)] AEnum val) {{ }}
+ public static void TestMethod7([ConstantExpected(Min=null, Max=null)] AEnum val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ One,
+ Two
+}}
+";
+ await TestCSAsync(csInput);
+ }
+
[Fact]
public static async Task TestConstantExpectedSupportedComplexTypesAsync()
{
@@ -348,6 +384,42 @@ await TestCSAsync(csInput,
.WithLocation(0));
}
+ [Theory]
+ [InlineData("sbyte", "AEnum.Five", "AEnum.Two")]
+ [InlineData("short", "AEnum.Five", "AEnum.Two")]
+ [InlineData("int", "AEnum.Five", "AEnum.Two")]
+ [InlineData("long", "AEnum.Five", "AEnum.Two")]
+ [InlineData("byte", "AEnum.Five", "AEnum.Two")]
+ [InlineData("ushort", "AEnum.Five", "AEnum.Two")]
+ [InlineData("uint", "AEnum.Five", "AEnum.Two")]
+ [InlineData("ulong", "AEnum.Five", "AEnum.Two")]
+ public static async Task TestEnumConstantExpectedInvertedConstantTypeErrorAsync(string type, string min, string max)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod([{{|#0:ConstantExpected(Min = {min}, Max = {max})|}}] {type} val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One = 1,
+ Two = 1 << 1,
+ Three = 1 << 2,
+ Four = 1 << 3,
+ Five = 1 << 4
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvertedRangeRule)
+ .WithLocation(0));
+ }
+
[Theory]
[InlineData("sbyte", sbyte.MinValue, sbyte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
[InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
@@ -403,6 +475,70 @@ await TestCSAsync(csInput,
.WithArguments("Max", type));
}
+ [Theory]
+ [InlineData("sbyte", sbyte.MinValue, sbyte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("short", short.MinValue, short.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("int", int.MinValue, int.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("long", long.MinValue, long.MaxValue, "ulong.MaxValue", "ulong.MaxValue", "false", "true")]
+ [InlineData("byte", byte.MinValue, byte.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("ushort", ushort.MinValue, ushort.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("uint", uint.MinValue, uint.MaxValue, "long.MinValue", "long.MaxValue", "false", "true")]
+ [InlineData("ulong", ulong.MinValue, ulong.MaxValue, "long.MinValue", "-1", "false", "true")]
+ public static async Task TestEnumConstantExpectedInvalidBoundsAsync(string type, object min, object max, string min1, string max1, string badMinValue, string badMaxValue)
+ {
+ string minString = min.ToString();
+ string maxString = max.ToString();
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod([ConstantExpected({{|#0:Min = {min1}|}})] AEnum val) {{ }}
+ public static void TestMethod2([ConstantExpected({{|#1:Min = {min1}|}}, {{|#2:Max = {max1}|}})] AEnum val) {{ }}
+ public static void TestMethod3([ConstantExpected({{|#3:Max = {max1}|}})] AEnum val) {{ }}
+ public static void TestMethod4([ConstantExpected({{|#4:Min = {badMinValue}|}}, {{|#5:Max = {max1}|}})] AEnum val) {{ }}
+ public static void TestMethod5([ConstantExpected({{|#6:Min = {min1}|}}, {{|#7:Max = {badMaxValue}|}})] AEnum val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One = 1,
+ Two = 1 << 1,
+ Three = 1 << 2,
+ Four = 1 << 3,
+ Five = 1 << 4
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(0)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(1)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(2)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(3)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
+ .WithLocation(4)
+ .WithArguments("Min", "AEnum"),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(5)
+ .WithArguments("Max", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.InvalidBoundsRule)
+ .WithLocation(6)
+ .WithArguments("Min", minString, maxString),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1860.IncompatibleConstantTypeRule)
+ .WithLocation(7)
+ .WithArguments("Max", "AEnum"));
+ }
+
[Theory]
[InlineData("char", "'A'", "'Z'", "'A'", "(char)('A'+'\\u0001')")]
[InlineData("sbyte", "10", "20", "10", "2*5")]
@@ -450,6 +586,58 @@ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
await TestCSAsync(csInput);
}
+ [Theory]
+ [InlineData("sbyte", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("short", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("int", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("long", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("byte", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("ushort", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("uint", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ [InlineData("ulong", "AEnum.One", "AEnum.Five", "AEnum.Two", "AEnum.One | AEnum.Two")]
+ public static async Task TestEnumArgumentConstantAsync(string type, string minValue, string maxValue, string value, string expression)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod()
+ {{
+ TestMethodWithConstant({value});
+ TestMethodWithConstant({expression});
+ TestMethodWithConstrainedConstant({value});
+ TestMethodWithConstrainedConstant({expression});
+ TestMethodGeneric({value});
+ TestMethodGeneric({expression});
+ GenericClass.TestMethodGeneric({value});
+ GenericClass.TestMethodGeneric({expression});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] AEnum val) {{ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {minValue}, Max = {maxValue})] AEnum val) {{ }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+
+ public static class GenericClass
+ {{
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One = 1,
+ Two = 1 << 1,
+ Three = 1 << 2,
+ Four = 1 << 3,
+ Five = 1 << 4
+}}
+";
+ await TestCSAsync(csInput);
+ }
+
[Theory]
[InlineData("char")]
[InlineData("sbyte")]
@@ -496,6 +684,54 @@ await TestCSAsync(csInput,
.WithLocation(2));
}
+ [Theory]
+ [InlineData("sbyte")]
+ [InlineData("short")]
+ [InlineData("int")]
+ [InlineData("long")]
+ [InlineData("byte")]
+ [InlineData("ushort")]
+ [InlineData("uint")]
+ [InlineData("ulong")]
+ public static async Task TestEnumArgumentNotConstantAsync(string type)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod(AEnum nonConstant)
+ {{
+ TestMethodWithConstant({{|#0:nonConstant|}});
+ TestMethodGeneric({{|#1:nonConstant|}});
+ GenenricClass.TestMethodGeneric({{|#2:nonConstant|}});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] AEnum val) {{ }}
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+
+ public static class GenenricClass
+ {{
+ public static void TestMethodGeneric([ConstantExpected] T val) {{ }}
+ }}
+}}
+
+public enum AEnum : {type}
+{{
+ One,
+ Two
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
+ .WithLocation(0),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
+ .WithLocation(1),
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantNotConstantRule)
+ .WithLocation(2));
+ }
+
[Theory]
[InlineData("char", "(char)(object)10.5")]
[InlineData("string", "(string)(object)20")]
@@ -569,6 +805,47 @@ await TestCSAsync(csInput,
.WithArguments(min.Trim('\''), max.Trim('\'')));
}
+ [Theory]
+ [InlineData("sbyte", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("short", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("int", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("long", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("byte", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("ushort", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("uint", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ [InlineData("ulong", "AEnum.Three", "AEnum.Four", "AEnum.Five")]
+ public static async Task TestEnumArgumentOutOfBoundsConstantAsync(string type, string min, string max, string testValue)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod()
+ {{
+ TestMethodWithConstant({{|#0:{testValue}|}});
+ }}
+ public static void TestMethodWithConstant([ConstantExpected(Min = {min}, Max = {max})] AEnum val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One,
+ Two,
+ Three,
+ Four,
+ Five
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantOutOfBoundsRule)
+ .WithLocation(0)
+ .WithArguments("3", "4"));
+ }
+
[Fact]
public static async Task TestArgumentInvalidGenericTypeParameterConstantAsync()
{
@@ -633,6 +910,50 @@ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {mi
await TestCSAsync(csInput);
}
+ [Theory]
+ [InlineData("sbyte", "AEnum.Two", "AEnum.Three")]
+ [InlineData("short", "AEnum.Two", "AEnum.Three")]
+ [InlineData("int", "AEnum.Two", "AEnum.Three")]
+ [InlineData("long", "AEnum.Two", "AEnum.Three")]
+ [InlineData("byte", "AEnum.Two", "AEnum.Three")]
+ [InlineData("ushort", "AEnum.Two", "AEnum.Three")]
+ [InlineData("uint", "AEnum.Two", "AEnum.Three")]
+ [InlineData("ulong", "AEnum.Two", "AEnum.Three")]
+ public static async Task TestEnumConstantCompositionAsync(string type, string min, string max)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethod([ConstantExpected] AEnum constant)
+ {{
+ TestMethodWithConstant(constant);
+ }}
+ public static void TestMethodWithConstant([ConstantExpected] AEnum val) {{ }}
+ public static void TestMethodConstrained([ConstantExpected(Min = {min}, Max = {max})] AEnum constant)
+ {{
+ TestMethodWithConstant(constant);
+ TestMethodWithConstrainedConstant(constant);
+ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] AEnum val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One = 1,
+ Two = 1 << 1,
+ Three = 1 << 2,
+ Four = 1 << 3,
+ Five = 1 << 4
+}}
+";
+ await TestCSAsync(csInput);
+ }
+
[Fact]
public static async Task TestConstantCompositionStringAsync()
{
@@ -688,6 +1009,47 @@ await TestCSAsync(csInput,
.WithArguments(minValue.ToString(), maxValue.ToString()));
}
+ [Theory]
+ [InlineData("sbyte", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("short", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("int", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("long", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("byte", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("ushort", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("uint", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ [InlineData("ulong", "AEnum.Two", "AEnum.Three", "AEnum.Four", 2, 4)]
+ public static async Task TestEnumConstantCompositionOutOfBoundsAsync(string type, string min, string max, string outOfBoundMax, object minValue, object maxValue)
+ {
+ string csInput = @$"
+using System;
+using System.Diagnostics.CodeAnalysis;
+#nullable enable
+
+public class Test
+{{
+ public static void TestMethodConstrained([ConstantExpected(Min = {min}, Max = {outOfBoundMax})] AEnum constant)
+ {{
+ TestMethodWithConstrainedConstant({{|#0:constant|}});
+ }}
+ public static void TestMethodWithConstrainedConstant([ConstantExpected(Min = {min}, Max = {max})] AEnum val) {{ }}
+}}
+
+public enum AEnum : {type}
+{{
+ Zero,
+ One = 1,
+ Two = 1 << 1,
+ Three = 1 << 2,
+ Four = 1 << 3,
+ Five = 1 << 4
+}}
+";
+ await TestCSAsync(csInput,
+ VerifyCS.Diagnostic(ConstantExpectedAnalyzer.CA1861.ConstantOutOfBoundsRule)
+ .WithLocation(0)
+ .WithArguments(minValue.ToString(), maxValue.ToString()));
+ }
+
[Fact]
public static async Task TestConstantCompositionNotSameTypeAsync()
{
From 65de245d1175012fbaef73430df5298e43b74cfa Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 27 Aug 2022 10:32:22 +0800
Subject: [PATCH 17/27] Fix RS1032
---
.../MicrosoftNetCoreAnalyzersResources.resx | 16 +++++-----
.../MicrosoftNetCoreAnalyzersResources.cs.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.de.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.es.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.fr.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.it.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ja.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ko.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.pl.xlf | 32 +++++++++----------
...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.ru.xlf | 32 +++++++++----------
.../MicrosoftNetCoreAnalyzersResources.tr.xlf | 32 +++++++++----------
...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 32 +++++++++----------
...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 32 +++++++++----------
14 files changed, 216 insertions(+), 216 deletions(-)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
index 0911b461c7..7783c2ce38 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
@@ -1877,28 +1877,28 @@
The parameter expects a constant for optimal performance.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The Min and Max values are inverted.
+ The Min and Max values are inverted
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotationSpecify a culture or use an invariant version
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 889996c2aa..32ad885ee1 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 f2c9bc4062..8d27750403 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 69494fe382..1022eacf96 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 1378fb4baa..4d5df455ab 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 9ebe3e1ef1..b517a0cf39 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 08cab96b87..54ee9ca82d 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
index 94ca45ccc0..829b4cf23a 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 42c756b9eb..5e4bcadd9a 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 e24fc9502c..ffc5b025a0 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,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 09dd3e865a..38a7a9f7e3 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 d4f304c8bc..ece9c7c30c 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -193,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 4af1b44e48..2c15286cdc 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,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
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 a7c25a9765..b3b7cca6f0 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,43 +193,43 @@
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
- The ConstantExpected attribute is required for the parameter due to the parent method annotation.
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
+ The ConstantExpected attribute is required for the parameter due to the parent method annotation
- The '{0}' value is not compatible with parameter type of '{1}'.
- The '{0}' value is not compatible with parameter type of '{1}'.
+ The '{0}' value is not compatible with parameter type of '{1}'
+ The '{0}' value is not compatible with parameter type of '{1}'
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
- The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'.
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
+ The '{0}' value does not fit within the parameter value bounds of '{1}' to '{2}'
- The constant is not of the same '{0}' type as the parameter.
- The constant is not of the same '{0}' type as the parameter.
+ The constant is not of the same '{0}' type as the parameter
+ The constant is not of the same '{0}' type as the parameter
- The Min and Max values are inverted.
- The Min and Max values are inverted.
+ The Min and Max values are inverted
+ The Min and Max values are inverted
- The argument should be a constant for optimal performance.
- The argument should be a constant for optimal performance.
+ The argument should be a constant for optimal performance
+ The argument should be a constant for optimal performance
- The '{0}' type is not supported for ConstantExpected attribute.
- The '{0}' type is not supported for ConstantExpected attribute.
+ The '{0}' type is not supported for ConstantExpected attribute
+ The '{0}' type is not supported for ConstantExpected attribute
- The constant does not fit within the value bounds of '{0}' to '{1}'.
- The constant does not fit within the value bounds of '{0}' to '{1}'.
+ The constant does not fit within the value bounds of '{0}' to '{1}'
+ The constant does not fit within the value bounds of '{0}' to '{1}'
From 04ad5b1c410c608f9996332bc986537e1dd93a0c Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 27 Aug 2022 10:36:24 +0800
Subject: [PATCH 18/27] Fix IDE0200: Lambda expression can be removed
---
.../Performance/CSharpConstantExpectedAnalyzer.cs | 2 +-
.../Performance/ConstantExpectedAnalyzer.cs | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 7c68c609b4..068b3d2a79 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -20,7 +20,7 @@ internal sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext context)
{
- context.RegisterSyntaxNodeAction(context => OnAttributeNode(context), SyntaxKind.Attribute);
+ context.RegisterSyntaxNodeAction(OnAttributeNode, SyntaxKind.Attribute);
}
private void OnAttributeNode(SyntaxNodeAnalysisContext context)
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
index 91715c0a82..4b426bc570 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.cs
@@ -126,7 +126,7 @@ public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
- context.RegisterCompilationStartAction(context => OnCompilationStart(context));
+ context.RegisterCompilationStartAction(OnCompilationStart);
}
private void OnCompilationStart(CompilationStartAnalysisContext context)
@@ -136,7 +136,7 @@ private void OnCompilationStart(CompilationStartAnalysisContext context)
return;
}
context.RegisterOperationAction(OnInvocation, OperationKind.Invocation);
- context.RegisterSymbolAction(context => OnMethodSymbol(context), SymbolKind.Method);
+ context.RegisterSymbolAction(OnMethodSymbol, SymbolKind.Method);
RegisterAttributeSyntax(context);
}
@@ -457,7 +457,7 @@ public static (object? MinConstant, object? MaxConstant) GetAttributeConstants(A
private static bool TryGetMethodInterface(IMethodSymbol methodSymbol, [NotNullWhen(true)] out IMethodSymbol? interfaceMethodSymbol)
{
var explicitInterface = methodSymbol.ExplicitInterfaceImplementations
- .FirstOrDefault(exInterface => methodSymbol.IsImplementationOfInterfaceMember(exInterface));
+ .FirstOrDefault(methodSymbol.IsImplementationOfInterfaceMember);
if (explicitInterface is not null)
{
interfaceMethodSymbol = explicitInterface;
From 011d9ebb1224ce172d91057290aa8cbc81fd758c Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 27 Aug 2022 13:52:24 +0800
Subject: [PATCH 19/27] Rework attribute symbol matching
ConstantExpectedContext captures the INamedTypeSymbol and wrap methods related to checking with the ConstantExpected attribute
---
.../CSharpConstantExpectedAnalyzer.cs | 10 +-
...onstantExpectedAnalyzer.UnmanagedHelper.cs | 24 +-
.../Performance/ConstantExpectedAnalyzer.cs | 536 ++++++++++--------
3 files changed, 320 insertions(+), 250 deletions(-)
diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
index 068b3d2a79..ae87caec60 100644
--- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
+++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Performance/CSharpConstantExpectedAnalyzer.cs
@@ -10,7 +10,7 @@
namespace Microsoft.NetCore.CSharp.Analyzers.Performance
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
- internal sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
+ public sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
{
private static readonly CSharpDiagnosticHelper s_diagnosticHelper = new();
private static readonly IdentifierNameSyntax s_constantExpectedIdentifier = (IdentifierNameSyntax)SyntaxFactory.ParseName(ConstantExpected);
@@ -18,12 +18,12 @@ internal sealed class CSharpConstantExpectedAnalyzer : ConstantExpectedAnalyzer
protected override DiagnosticHelper Helper => s_diagnosticHelper;
- protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext context)
+ protected override void RegisterAttributeSyntax(CompilationStartAnalysisContext context, ConstantExpectedContext constantExpectedContext)
{
- context.RegisterSyntaxNodeAction(OnAttributeNode, SyntaxKind.Attribute);
+ context.RegisterSyntaxNodeAction(context => OnAttributeNode(context, constantExpectedContext), SyntaxKind.Attribute);
}
- private void OnAttributeNode(SyntaxNodeAnalysisContext context)
+ private void OnAttributeNode(SyntaxNodeAnalysisContext context, ConstantExpectedContext constantExpectedContext)
{
var attributeSyntax = (AttributeSyntax)context.Node;
var attributeName = attributeSyntax.Name;
@@ -35,7 +35,7 @@ private void OnAttributeNode(SyntaxNodeAnalysisContext context)
if (attributeSyntax.Parent.Parent is ParameterSyntax parameter)
{
var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameter);
- OnParameterWithConstantExpectedAttribute(parameterSymbol, context.ReportDiagnostic);
+ OnParameterWithConstantExpectedAttribute(parameterSymbol, constantExpectedContext, context.ReportDiagnostic);
}
}
diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
index af1ee792e7..5060578fd6 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/ConstantExpectedAnalyzer.UnmanagedHelper.cs
@@ -4,7 +4,6 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
-using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
@@ -127,9 +126,9 @@ private bool IsValidMinMax(AttributeData attributeData, T typeMin, T typeMax, ou
{
minValue = typeMin;
maxValue = typeMax;
- (object? min, object? max) = GetAttributeConstants(attributeData);
+ var ac = AttributeConstant.Get(attributeData);
errorFlags = ErrorKind.None;
- if (min is not null && _helper.TryTransformMin(min, out minValue, ref errorFlags))
+ if (ac.Min is not null && _helper.TryTransformMin(ac.Min, out minValue, ref errorFlags))
{
if (_helper.IsLessThan(minValue, typeMin) || _helper.IsLessThan(typeMax, minValue))
{
@@ -137,7 +136,7 @@ private bool IsValidMinMax(AttributeData attributeData, T typeMin, T typeMax, ou
}
}
- if (max is not null && _helper.TryTransformMax(max, out maxValue, ref errorFlags))
+ if (ac.Max is not null && _helper.TryTransformMax(ac.Max, out maxValue, ref errorFlags))
{
if (_helper.IsLessThan(maxValue, typeMin) || _helper.IsLessThan(typeMax, maxValue))
{
@@ -177,7 +176,7 @@ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter su
if (Parameter.Type.SpecialType != subsetCandidate.Parameter.Type.SpecialType ||
subsetCandidate is not UnmanagedConstantExpectedParameter subsetCandidateTParameter)
{
- validationDiagnostics = Diagnostic.Create(CA1861.ConstantInvalidConstantRule, argument.Syntax.GetLocation(), Parameter.Type.ToDisplayString());
+ validationDiagnostics = CreateConstantInvalidConstantRuleDiagnostic(argument);
return false;
}
@@ -187,23 +186,28 @@ public override bool ValidateParameterIsWithinRange(ConstantExpectedParameter su
validationDiagnostics = null;
return true;
}
- validationDiagnostics = Diagnostic.Create(CA1861.ConstantOutOfBoundsRule, argument.Syntax.GetLocation(), Min.ToString(), Max.ToString());
+ validationDiagnostics = CreateConstantOutOfBoundsRuleDiagnostic(argument, Min.ToString(), Max.ToString());
return false;
}
- public override bool ValidateValue(IArgumentOperation argument, object? constant, [NotNullWhen(false)] out Diagnostic? validationDiagnostics)
+ public override bool ValidateValue(IArgumentOperation argument, Optional
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 8d27750403..ee093284d6 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 1022eacf96..27f9df1a9b 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 4d5df455ab..3405093ab3 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 b517a0cf39..34b1886f61 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 54ee9ca82d..6e7aee3a0f 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 829b4cf23a..33d9fa157a 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 5e4bcadd9a..d903a65de1 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 ffc5b025a0..a9ec277c8f 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
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 38a7a9f7e3..3ecfc27a80 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 ece9c7c30c..62e5aafd72 100644
--- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
+++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 2c15286cdc..949e5cbb3c 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
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
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 b3b7cca6f0..24eaaefd3a 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
@@ -183,8 +183,8 @@
Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’}
- ConstantExpectedAttribute is not applied correctly on the parameter.
- ConstantExpectedAttribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
+ ConstantExpected attribute is not applied correctly on the parameter.
From 266fba8626626cf45fefa714a2993cb688ba7e5a Mon Sep 17 00:00:00 2001
From: WeiZheng <13881045+wzchua@users.noreply.github.com>
Date: Sat, 12 Nov 2022 08:38:22 +0800
Subject: [PATCH 25/27] Run pack
---
src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 6 +++---
.../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 6 +++---
src/NetAnalyzers/RulesMissingDocumentation.md | 8 ++------
3 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
index 67cf690569..4a50157bff 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md
@@ -1584,9 +1584,9 @@ It is more efficient to use 'Clear', instead of 'Fill' with default value.
|CodeFix|True|
---
-## [CA1856](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1856): Incorrect usage of ConstantExpected attribute
+## [CA1856](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1856): Incorrect usage of ConstantExpected attribute
-ConstantExpectedAttribute is not applied correctly on the parameter.
+ConstantExpected attribute is not applied correctly on the parameter.
|Item|Value|
|-|-|
@@ -1596,7 +1596,7 @@ ConstantExpectedAttribute is not applied correctly on the parameter.
|CodeFix|False|
---
-## [CA1857](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857): A constant is expected for the parameter
+## [CA1857](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857): A constant is expected for the parameter
The parameter expects a constant for optimal performance.
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index 12fbe29000..820fa1fb7d 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -307,9 +307,9 @@
"CA1856": {
"id": "CA1856",
"shortDescription": "Incorrect usage of ConstantExpected attribute",
- "fullDescription": "ConstantExpectedAttribute is not applied correctly on the parameter.",
+ "fullDescription": "ConstantExpected attribute is not applied correctly on the parameter.",
"defaultLevel": "error",
- "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1856",
+ "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1856",
"properties": {
"category": "Performance",
"isEnabledByDefault": true,
@@ -328,7 +328,7 @@
"shortDescription": "A constant is expected for the parameter",
"fullDescription": "The parameter expects a constant for optimal performance.",
"defaultLevel": "warning",
- "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857",
+ "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1857",
"properties": {
"category": "Performance",
"isEnabledByDefault": true,
diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md
index 7433ec0a00..acfaceed87 100644
--- a/src/NetAnalyzers/RulesMissingDocumentation.md
+++ b/src/NetAnalyzers/RulesMissingDocumentation.md
@@ -3,13 +3,9 @@
Rule ID | Missing Help Link | Title |
--------|-------------------|-------|
CA1311 | | Specify a culture or use an invariant version |
-CA1420 | | Property, type, or attribute requires runtime marshalling |
CA1421 | | This method uses runtime marshalling even when the 'DisableRuntimeMarshallingAttribute' is applied |
-CA1422 | | Validate platform compatibility |
CA1852 | | Seal internal types |
CA1853 | | Unnecessary call to 'Dictionary.ContainsKey(key)' |
CA1855 | | Prefer 'Clear' over 'Fill' |
-CA1856 | | Incorrect usage of ConstantExpected attribute |
-CA1857 | | A constant is expected for the parameter |
-CA2019 | | Improper 'ThreadStatic' field initialization |
-CA2259 | | 'ThreadStatic' only affects static fields |
+CA1856 | | Incorrect usage of ConstantExpected attribute |
+CA1857 | | A constant is expected for the parameter |
From 774008bce2da34531dc18ab43b17a8b762b72c85 Mon Sep 17 00:00:00 2001
From: Buyaa Namnan
Date: Tue, 15 Nov 2022 21:13:04 -0800
Subject: [PATCH 26/27] Apply suggestions from code review
---
src/NetAnalyzers/RulesMissingDocumentation.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md
index 5024769209..acfaceed87 100644
--- a/src/NetAnalyzers/RulesMissingDocumentation.md
+++ b/src/NetAnalyzers/RulesMissingDocumentation.md
@@ -8,4 +8,4 @@ CA1852 | | Unnecessary call to 'Dictionary.ContainsKey(key)' |
CA1855 | | Prefer 'Clear' over 'Fill' |
CA1856 | | Incorrect usage of ConstantExpected attribute |
-CA1857 | | A constant is expected for the parameter |
\ No newline at end of file
+CA1857 | | A constant is expected for the parameter |
From ca89072da2e8a719fa200addb04b4a20e39df3c1 Mon Sep 17 00:00:00 2001
From: Buyaa Namnan
Date: Tue, 15 Nov 2022 22:22:30 -0800
Subject: [PATCH 27/27] Fix generated file
---
src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
index 820fa1fb7d..576fc974e9 100644
--- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
+++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif
@@ -5,7 +5,7 @@
{
"tool": {
"name": "Microsoft.CodeAnalysis.CSharp.NetAnalyzers",
- "version": "7.0.0",
+ "version": "8.0.0",
"language": "en-US"
},
"rules": {
@@ -576,7 +576,7 @@
{
"tool": {
"name": "Microsoft.CodeAnalysis.NetAnalyzers",
- "version": "7.0.0",
+ "version": "8.0.0",
"language": "en-US"
},
"rules": {
@@ -5853,7 +5853,7 @@
{
"tool": {
"name": "Microsoft.CodeAnalysis.VisualBasic.NetAnalyzers",
- "version": "7.0.0",
+ "version": "8.0.0",
"language": "en-US"
},
"rules": {