diff --git a/src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md b/src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md index 2028f53a53..3f3facd639 100644 --- a/src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md @@ -3,3 +3,10 @@ Rule ID | Category | Severity | Notes ---------|----------|----------|-------------------- BDN1305 | Usage | Error | [ParamsSource] cannot reference write-only property + + +### Removed Rules + +Rule ID | Category | Severity | Notes +---------|----------|----------|-------------------- +BDN1100 | Usage | Error | Rule removed as GenericTypeArguments now supports abstract classes \ No newline at end of file diff --git a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs index 8bd42ac17b..017e1d920c 100644 --- a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs +++ b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs @@ -720,37 +720,7 @@ internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttri return ResourceManager.GetString("General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title", resourceCulture); } } - - /// - /// Looks up a localized string similar to A benchmark class annotated with a [GenericTypeArguments] attribute must be non-abstract. - /// - internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Description { - get { - return ResourceManager.GetString("General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_De" + - "scription", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attribute [GenericTypeArguments] can only be applied to a non-abstract class. - /// - internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_MessageFormat { - get { - return ResourceManager.GetString("General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Me" + - "ssageFormat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Benchmark classes annotated with the [GenericTypeArguments] attribute must be non-abstract. - /// - internal static string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Title { - get { - return ResourceManager.GetString("General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Ti" + - "tle", resourceCulture); - } - } - + /// /// Looks up a localized string similar to The number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class. /// diff --git a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx index 5ba7f21797..a9c4d8f97a 100644 --- a/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx +++ b/src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx @@ -135,15 +135,9 @@ A benchmark class must be an instance class - - A benchmark class annotated with a [GenericTypeArguments] attribute must be non-abstract - Benchmark class '{0}' cannot be static - - Attribute [GenericTypeArguments] can only be applied to a non-abstract class - Referenced generic benchmark class '{0}' has no [GenericTypeArguments] attribute(s) @@ -153,9 +147,6 @@ Benchmark classes must be non-static - - Benchmark classes annotated with the [GenericTypeArguments] attribute must be non-abstract - Generic benchmark classes must be annotated with at least one [GenericTypeArguments] attribute diff --git a/src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs b/src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs index 9d91630675..14d2a3ac90 100644 --- a/src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs +++ b/src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs @@ -7,7 +7,6 @@ public static class DiagnosticIds public const string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed = "BDN1002"; public const string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract = "BDN1003"; public const string BenchmarkRunner_Run_GenericTypeArgumentClassMustBeAnnotatedWithAGenericTypeArgumentsAttribute = "BDN1004"; - public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract = "BDN1100"; public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric = "BDN1101"; public const string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount = "BDN1102"; public const string General_BenchmarkClass_MethodMustBePublic = "BDN1103"; diff --git a/src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs b/src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs index 08d93b77cb..891076fcf0 100644 --- a/src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs +++ b/src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs @@ -12,15 +12,6 @@ namespace BenchmarkDotNet.Analyzers.General; [DiagnosticAnalyzer(LanguageNames.CSharp)] public class BenchmarkClassAnalyzer : DiagnosticAnalyzer { - internal static readonly DiagnosticDescriptor ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule = new( - DiagnosticIds.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract, - AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Title)), - AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_MessageFormat)), - "Usage", - DiagnosticSeverity.Error, - isEnabledByDefault: true, - description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Description))); - internal static readonly DiagnosticDescriptor ClassWithGenericTypeArgumentsAttributeMustBeGenericRule = new( DiagnosticIds.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric, AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title)), @@ -92,7 +83,6 @@ public class BenchmarkClassAnalyzer : DiagnosticAnalyzer public override ImmutableArray SupportedDiagnostics => new DiagnosticDescriptor[] { - ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule, ClassWithGenericTypeArgumentsAttributeMustBeGenericRule, GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCountRule, MethodMustBePublicRule, @@ -149,11 +139,6 @@ private static void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context) { foreach (var genericTypeArgumentsAttribute in genericTypeArgumentsAttributes) { - if (classAbstractModifier.HasValue) - { - context.ReportDiagnostic(Diagnostic.Create(ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule, genericTypeArgumentsAttribute.GetLocation())); - } - if (classDeclarationSyntax.TypeParameterList == null || classDeclarationSyntax.TypeParameterList.Parameters.Count == 0) { context.ReportDiagnostic(Diagnostic.Create(ClassWithGenericTypeArgumentsAttributeMustBeGenericRule, genericTypeArgumentsAttribute.GetLocation())); diff --git a/tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/General/BenchmarkClassAnalyzerTests.cs b/tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/General/BenchmarkClassAnalyzerTests.cs index 6ebb4d9798..9cff31cf32 100644 --- a/tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/General/BenchmarkClassAnalyzerTests.cs +++ b/tests/BenchmarkDotNet.Analyzers.Tests/AnalyzerTests/General/BenchmarkClassAnalyzerTests.cs @@ -35,46 +35,6 @@ public void BenchmarkMethod() } } - public class ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract : AnalyzerTestFixture - { - public ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract() : base(BenchmarkClassAnalyzer.ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule) { } - - [Theory, CombinatorialData] - public async Task Abstract_class_annotated_with_at_least_one_generictypearguments_attribute_should_trigger_diagnostic( - [CombinatorialRange(1, 2)] int genericTypeArgumentsAttributeUsageCount, - [CombinatorialMemberData(nameof(BenchmarkAttributeUsagesEnumerableLocal))] string benchmarkAttributeUsage) - { - const string benchmarkClassName = "BenchmarkClass"; - - var genericTypeArgumentsAttributeUsages = Enumerable.Repeat("[{{|#{0}:GenericTypeArguments(typeof(int))|}}]", genericTypeArgumentsAttributeUsageCount).Select((a, i) => string.Format(a, i)); - - var testCode = /* lang=c#-test */ $$""" - using BenchmarkDotNet.Attributes; - - {{string.Join("\n", genericTypeArgumentsAttributeUsages)}} - public abstract class {{benchmarkClassName}} - { - {{benchmarkAttributeUsage}} - public void BenchmarkMethod() - { - - } - } - """; - - TestCode = testCode; - - for (var i = 0; i < genericTypeArgumentsAttributeUsageCount; i++) - { - AddExpectedDiagnostic(i); - } - - await RunAsync(); - } - - public static IEnumerable BenchmarkAttributeUsagesEnumerableLocal => BenchmarkAttributeUsagesEnumerable; - } - public class ClassWithGenericTypeArgumentsAttributeMustBeGeneric : AnalyzerTestFixture { public ClassWithGenericTypeArgumentsAttributeMustBeGeneric() : base(BenchmarkClassAnalyzer.ClassWithGenericTypeArgumentsAttributeMustBeGenericRule) { }