Skip to content

Commit 3178a18

Browse files
committed
* Change diagnostic ID increment ordering
* Add a rule that the benchmark class referenced in the type argument of the BenchmarkRunner.Run method cannot be abstract
1 parent 6db4e7b commit 3178a18

File tree

6 files changed

+182
-87
lines changed

6 files changed

+182
-87
lines changed

src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,31 @@
66
Rule ID | Category | Severity | Notes
77
---------|----------|----------|--------------------
88
BDN1000 | Usage | Error | BDN1000_BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods
9-
BDN1001 | Usage | Error | BDN1001_General_BenchmarkClass_MethodMustBePublic
10-
BDN1002 | Usage | Error | BDN1002_General_BenchmarkClass_MethodMustBeNonGeneric
11-
BDN1003 | Usage | Error | BDN1003_General_BenchmarkClass_ClassMustBePublic
12-
BDN1004 | Usage | Error | BDN1004_General_BenchmarkClass_ClassMustBeNonStatic
13-
BDN1005 | Usage | Error | BDN1005_General_BenchmarkClass_ClassMustBeNonAbstract
14-
BDN1006 | Usage | Error | BDN1006_General_BenchmarkClass_ClassMustBeNonGeneric
15-
BDN1007 | Usage | Error | BDN1007_General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric
16-
BDN1008 | Usage | Error | BDN1008_General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount
17-
BDN1009 | Usage | Error | BDN1009_General_BenchmarkClass_ClassMustBeUnsealed
18-
BDN1010 | Usage | Error | BDN1010_General_BenchmarkClass_OnlyOneMethodCanBeBaseline
19-
BDN1011 | Usage | Error | BDN1011_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField
20-
BDN1012 | Usage | Error | BDN1012_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty
21-
BDN1013 | Usage | Error | BDN1013_Attributes_GeneralParameterAttributes_FieldMustBePublic
22-
BDN1014 | Usage | Error | BDN1014_Attributes_GeneralParameterAttributes_PropertyMustBePublic
23-
BDN1015 | Usage | Error | BDN1015_Attributes_GeneralParameterAttributes_NotValidOnReadonlyField
24-
BDN1016 | Usage | Error | BDN1016_Attributes_GeneralParameterAttributes_NotValidOnConstantField
25-
BDN1017 | Usage | Error | BDN1017_Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly
26-
BDN1018 | Usage | Error | BDN1018_Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter
27-
BDN1019 | Usage | Error | BDN1019_Attributes_ParamsAttribute_MustHaveValues
28-
BDN1020 | Usage | Error | BDN1020_Attributes_ParamsAttribute_UnexpectedValueType
29-
BDN1021 | Usage | Warning | BDN1021_Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute
30-
BDN1022 | Usage | Error | BDN1022_Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType
31-
BDN1023 | Usage | Error | BDN1023_Attributes_ParamsAllValues_PropertyOrFieldTypeMustBeEnumOrBool
32-
BDN1024 | Usage | Error | BDN1024_Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute
33-
BDN1025 | Usage | Error | BDN1025_Attributes_ArgumentsAttribute_MethodWithoutAttributeMustHaveNoParameters
34-
BDN1026 | Usage | Error | BDN1026_Attributes_ArgumentsAttribute_MustHaveMatchingValueCount
35-
BDN1027 | Usage | Error | BDN1027_Attributes_ArgumentsAttribute_MustHaveMatchingValueType
9+
BDN1001 | Usage | Error | BDN1001_BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract
10+
BDN1100 | Usage | Error | BDN1100_General_BenchmarkClass_MethodMustBePublic
11+
BDN1101 | Usage | Error | BDN1101_General_BenchmarkClass_MethodMustBeNonGeneric
12+
BDN1102 | Usage | Error | BDN1102_General_BenchmarkClass_ClassMustBePublic
13+
BDN1103 | Usage | Error | BDN1103_General_BenchmarkClass_ClassMustBeNonStatic
14+
BDN1104 | Usage | Error | BDN1104_General_BenchmarkClass_ClassMustBeNonAbstract
15+
BDN1105 | Usage | Error | BDN1105_General_BenchmarkClass_ClassMustBeNonGeneric
16+
BDN1106 | Usage | Error | BDN1106_General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric
17+
BDN1107 | Usage | Error | BDN1107_General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount
18+
BDN1108 | Usage | Error | BDN1108_General_BenchmarkClass_ClassMustBeUnsealed
19+
BDN1109 | Usage | Error | BDN1109_General_BenchmarkClass_OnlyOneMethodCanBeBaseline
20+
BDN1200 | Usage | Error | BDN1200_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField
21+
BDN1201 | Usage | Error | BDN1201_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty
22+
BDN1202 | Usage | Error | BDN1202_Attributes_GeneralParameterAttributes_FieldMustBePublic
23+
BDN1203 | Usage | Error | BDN1203_Attributes_GeneralParameterAttributes_PropertyMustBePublic
24+
BDN1204 | Usage | Error | BDN1204_Attributes_GeneralParameterAttributes_NotValidOnReadonlyField
25+
BDN1205 | Usage | Error | BDN1205_Attributes_GeneralParameterAttributes_NotValidOnConstantField
26+
BDN1206 | Usage | Error | BDN1206_Attributes_GeneralParameterAttributes_PropertyCannotBeInitOnly
27+
BDN1207 | Usage | Error | BDN1207_Attributes_GeneralParameterAttributes_PropertyMustHavePublicSetter
28+
BDN1300 | Usage | Error | BDN1300_Attributes_ParamsAttribute_MustHaveValues
29+
BDN1301 | Usage | Error | BDN1301_Attributes_ParamsAttribute_UnexpectedValueType
30+
BDN1302 | Usage | Warning | BDN1302_Attributes_ParamsAttribute_UnnecessarySingleValuePassedToAttribute
31+
BDN1303 | Usage | Error | BDN1303_Attributes_ParamsAllValuesAttribute_NotAllowedOnFlagsEnumPropertyOrFieldType
32+
BDN1304 | Usage | Error | BDN1304_Attributes_ParamsAllValues_PropertyOrFieldTypeMustBeEnumOrBool
33+
BDN1400 | Usage | Error | BDN1400_Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute
34+
BDN1401 | Usage | Error | BDN1401_Attributes_ArgumentsAttribute_MethodWithoutAttributeMustHaveNoParameters
35+
BDN1402 | Usage | Error | BDN1402_Attributes_ArgumentsAttribute_MustHaveMatchingValueCount
36+
BDN1403 | Usage | Error | BDN1403_Attributes_ArgumentsAttribute_MustHaveMatchingValueType

src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs

Lines changed: 32 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.resx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,20 @@
123123
<data name="BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_MessageFormat" xml:space="preserve">
124124
<value>Intended benchmark class '{0}' has no method(s) annotated with the [Benchmark] attribute</value>
125125
</data>
126+
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat" xml:space="preserve">
127+
<value>Referenced benchmark class '{0}' cannot be abstract</value>
128+
</data>
126129
<data name="BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Title" xml:space="preserve">
127130
<value>Benchmark class has no annotated method(s)</value>
128131
</data>
132+
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title" xml:space="preserve">
133+
<value>Benchmark classes must be non-abstract</value>
134+
</data>
129135
<data name="General_BenchmarkClass_ClassMustBeNonStatic_Description" xml:space="preserve">
130136
<value>A benchmark class must be an instance class</value>
131137
</data>
132138
<data name="General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract_Description" xml:space="preserve">
133-
<value>A benchmark class annotated with the [GenericTypeArguments] attribute must be non-abstract</value>
139+
<value>A benchmark class annotated with a [GenericTypeArguments] attribute must be non-abstract</value>
134140
</data>
135141
<data name="General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat" xml:space="preserve">
136142
<value>Benchmark class '{0}' cannot be static</value>
@@ -175,10 +181,10 @@
175181
<value>A method annotated with the [Benchmark] attribute must be non-generic</value>
176182
</data>
177183
<data name="General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Description" xml:space="preserve">
178-
<value>The number of type arguments passed to the [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>
184+
<value>The number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>
179185
</data>
180186
<data name="General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Description" xml:space="preserve">
181-
<value>A benchmark class annotated with the [GenericTypeArguments] attribute must be generic, having between one to three type parameters</value>
187+
<value>A benchmark class annotated with a [GenericTypeArguments] attribute must be generic, having between one to three type parameters</value>
182188
</data>
183189
<data name="General_BenchmarkClass_MethodMustBePublic_MessageFormat" xml:space="preserve">
184190
<value>The benchmark method '{0}' must be public</value>
@@ -202,10 +208,10 @@
202208
<value>Benchmark methods must be non-generic</value>
203209
</data>
204210
<data name="General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount_Title" xml:space="preserve">
205-
<value>Number of type arguments passed to the [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>
211+
<value>Number of type arguments passed to a [GenericTypeArguments] attribute must match the number of type parameters on the targeted benchmark class</value>
206212
</data>
207213
<data name="General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric_Title" xml:space="preserve">
208-
<value>Benchmark classes annotated with the [GenericTypeArguments] attribute must be generic</value>
214+
<value>Benchmark classes annotated with a [GenericTypeArguments] attribute must be generic</value>
209215
</data>
210216
<data name="General_BenchmarkClass_OnlyOneMethodCanBeBaseline_Title" xml:space="preserve">
211217
<value>Only one benchmark method can be baseline</value>
@@ -349,4 +355,7 @@ Either add the [Arguments] attribute(s) or remove the parameters.</value>
349355
<data name="Attributes_ArgumentsAttribute_RequiresBenchmarkAttribute_MessageFormat" xml:space="preserve">
350356
<value>The [Arguments] attribute can only be used on methods annotated with the [Benchmark] attribute</value>
351357
</data>
358+
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description" xml:space="preserve">
359+
<value>A benchmark class referenced in the BenchmarkRunner.Run method must be non-abstract</value>
360+
</data>
352361
</root>

src/BenchmarkDotNet.Analyzers/BenchmarkRunner/RunAnalyzer.cs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,19 @@ public class RunAnalyzer : DiagnosticAnalyzer
1818
isEnabledByDefault: true,
1919
description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description)));
2020

21-
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(TypeArgumentClassMissingBenchmarkMethodsRule);
21+
internal static readonly DiagnosticDescriptor TypeArgumentClassMustBeNonAbstractRule = new DiagnosticDescriptor(DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract,
22+
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title)),
23+
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat)),
24+
"Usage",
25+
DiagnosticSeverity.Error,
26+
isEnabledByDefault: true,
27+
description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description)));
28+
29+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
30+
[
31+
TypeArgumentClassMissingBenchmarkMethodsRule,
32+
TypeArgumentClassMustBeNonAbstractRule
33+
];
2234

2335
public override void Initialize(AnalysisContext analysisContext)
2436
{
@@ -85,14 +97,19 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
8597
var benchmarkAttributeTypeSymbol = AnalyzerHelper.GetBenchmarkAttributeTypeSymbol(context.Compilation);
8698
if (benchmarkAttributeTypeSymbol == null)
8799
{
88-
ReportDiagnostic();
100+
ReportDiagnostic(TypeArgumentClassMissingBenchmarkMethodsRule);
89101

90102
return;
91103
}
92104

93105
if (!HasBenchmarkAttribute())
94106
{
95-
ReportDiagnostic();
107+
ReportDiagnostic(TypeArgumentClassMissingBenchmarkMethodsRule);
108+
}
109+
110+
if (benchmarkClassTypeSymbol.IsAbstract)
111+
{
112+
ReportDiagnostic(TypeArgumentClassMustBeNonAbstractRule);
96113
}
97114

98115
return;
@@ -119,9 +136,9 @@ bool HasBenchmarkAttribute()
119136
return false;
120137
}
121138

122-
void ReportDiagnostic()
139+
void ReportDiagnostic(DiagnosticDescriptor diagnosticDescriptor)
123140
{
124-
context.ReportDiagnostic(Diagnostic.Create(TypeArgumentClassMissingBenchmarkMethodsRule, Location.Create(context.FilterTree, genericMethod.TypeArgumentList.Arguments.Span), benchmarkClassTypeSymbol.ToString()));
141+
context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, Location.Create(context.FilterTree, genericMethod.TypeArgumentList.Arguments.Span), benchmarkClassTypeSymbol.ToString()));
125142
}
126143
}
127144
}

0 commit comments

Comments
 (0)