Skip to content

Commit 1f42b60

Browse files
committed
Move "Benchmark class must be public" to Run analyzer
1 parent 69a6ad3 commit 1f42b60

File tree

8 files changed

+187
-158
lines changed

8 files changed

+187
-158
lines changed

src/BenchmarkDotNet.Analyzers/AnalyzerReleases.Unshipped.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
Rule ID | Category | Severity | Notes
77
---------|----------|----------|--------------------
88
BDN1000 | Usage | Error | BDN1000_BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods
9-
BDN1001 | Usage | Error | BDN1001_BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract
10-
BDN1002 | Usage | Error | BDN1002_BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed
9+
BDN1001 | Usage | Error | BDN1001_BenchmarkRunner_Run_TypeArgumentClassMustBePublic
10+
BDN1002 | Usage | Error | BDN1002_BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract
11+
BDN1003 | Usage | Error | BDN1003_BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed
1112
BDN1100 | Usage | Error | BDN1100_General_BenchmarkClass_MethodMustBePublic
1213
BDN1101 | Usage | Error | BDN1101_General_BenchmarkClass_MethodMustBeNonGeneric
13-
BDN1102 | Usage | Error | BDN1102_General_BenchmarkClass_ClassMustBePublic
14-
BDN1103 | Usage | Error | BDN1103_General_BenchmarkClass_ClassMustBeNonStatic
15-
BDN1104 | Usage | Error | BDN1104_General_BenchmarkClass_ClassMustBeNonAbstract
16-
BDN1105 | Usage | Error | BDN1105_General_BenchmarkClass_ClassMustBeNonGeneric
17-
BDN1106 | Usage | Error | BDN1106_General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric
18-
BDN1107 | Usage | Error | BDN1107_General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount
19-
BDN1108 | Usage | Error | BDN1108_General_BenchmarkClass_OnlyOneMethodCanBeBaseline
14+
BDN1102 | Usage | Error | BDN1102_General_BenchmarkClass_ClassMustBeNonStatic
15+
BDN1103 | Usage | Error | BDN1103_General_BenchmarkClass_ClassMustBeNonAbstract
16+
BDN1104 | Usage | Error | BDN1104_General_BenchmarkClass_ClassMustBeNonGeneric
17+
BDN1105 | Usage | Error | BDN1105_General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric
18+
BDN1106 | Usage | Error | BDN1106_General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount
19+
BDN1107 | Usage | Error | BDN1107_General_BenchmarkClass_OnlyOneMethodCanBeBaseline
2020
BDN1200 | Usage | Error | BDN1200_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField
2121
BDN1201 | Usage | Error | BDN1201_Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty
2222
BDN1202 | Usage | Error | BDN1202_Attributes_GeneralParameterAttributes_FieldMustBePublic

src/BenchmarkDotNet.Analyzers/BenchmarkDotNetAnalyzerResources.Designer.cs

Lines changed: 18 additions & 27 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: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,7 @@
156156
<data name="General_BenchmarkClass_GenericClassMustBeAbstractOrAnnotatedWithAGenericTypeArgumentsAttribute_Title" xml:space="preserve">
157157
<value>Benchmark classes can only be generic if they're either abstract or annotated with a [GenericTypeArguments] attribute</value>
158158
</data>
159-
<data name="General_BenchmarkClass_ClassMustBePublic_Description" xml:space="preserve">
160-
<value>A benchmark class must be public</value>
161-
</data>
162-
<data name="General_BenchmarkClass_ClassMustBePublic_MessageFormat" xml:space="preserve">
163-
<value>The benchmark class '{0}' must be public</value>
164-
</data>
165-
<data name="General_BenchmarkClass_ClassMustBePublic_Title" xml:space="preserve">
159+
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title" xml:space="preserve">
166160
<value>Benchmark classes must be public</value>
167161
</data>
168162
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed_Description" xml:space="preserve">
@@ -358,4 +352,7 @@ Either add the [Arguments] attribute(s) or remove the parameters.</value>
358352
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Description" xml:space="preserve">
359353
<value>A benchmark class referenced in the BenchmarkRunner.Run method must be non-abstract</value>
360354
</data>
355+
<data name="BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat" xml:space="preserve">
356+
<value>Referenced benchmark class '{0}' must be public</value>
357+
</data>
361358
</root>

src/BenchmarkDotNet.Analyzers/BenchmarkRunner/RunAnalyzer.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ public class RunAnalyzer : DiagnosticAnalyzer
1818
isEnabledByDefault: true,
1919
description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods_Description)));
2020

21+
internal static readonly DiagnosticDescriptor TypeArgumentClassMustBePublicRule = new DiagnosticDescriptor(DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBePublic,
22+
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBePublic_Title)),
23+
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBePublic_MessageFormat)),
24+
"Usage",
25+
DiagnosticSeverity.Error,
26+
isEnabledByDefault: true);
27+
2128
internal static readonly DiagnosticDescriptor TypeArgumentClassMustBeNonAbstractRule = new DiagnosticDescriptor(DiagnosticIds.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract,
2229
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_Title)),
2330
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract_MessageFormat)),
@@ -37,6 +44,7 @@ public class RunAnalyzer : DiagnosticAnalyzer
3744
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics =>
3845
[
3946
TypeArgumentClassMissingBenchmarkMethodsRule,
47+
TypeArgumentClassMustBePublicRule,
4048
TypeArgumentClassMustBeNonAbstractRule,
4149
TypeArgumentClassMustBeUnsealedRule
4250
];
@@ -82,6 +90,8 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
8290
return;
8391
}
8492

93+
// TODO: Support Type overloads that use the typeof() expression
94+
8595
if (memberAccessExpression.Name is not GenericNameSyntax genericMethod)
8696
{
8797
return;
@@ -116,6 +126,11 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
116126
ReportDiagnostic(TypeArgumentClassMissingBenchmarkMethodsRule);
117127
}
118128

129+
if (benchmarkClassTypeSymbol.DeclaredAccessibility != Accessibility.Public)
130+
{
131+
ReportDiagnostic(TypeArgumentClassMustBePublicRule);
132+
}
133+
119134
if (benchmarkClassTypeSymbol.IsAbstract)
120135
{
121136
ReportDiagnostic(TypeArgumentClassMustBeNonAbstractRule);
@@ -159,7 +174,7 @@ bool HasBenchmarkAttribute()
159174

160175
void ReportDiagnostic(DiagnosticDescriptor diagnosticDescriptor)
161176
{
162-
context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, Location.Create(context.FilterTree, genericMethod.TypeArgumentList.Arguments.Span), benchmarkClassTypeSymbol.ToString()));
177+
context.ReportDiagnostic(Diagnostic.Create(diagnosticDescriptor, Location.Create(context.FilterTree, genericMethod.TypeArgumentList.Arguments.Span), benchmarkClassTypeSymbol.Name));
163178
}
164179
}
165180
}

src/BenchmarkDotNet.Analyzers/DiagnosticIds.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
public static class DiagnosticIds
44
{
55
public const string BenchmarkRunner_Run_TypeArgumentClassMissingBenchmarkMethods = "BDN1000";
6-
public const string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract = "BDN1001";
7-
public const string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed = "BDN1002";
6+
public const string BenchmarkRunner_Run_TypeArgumentClassMustBePublic = "BDN1001";
7+
public const string BenchmarkRunner_Run_TypeArgumentClassMustBeNonAbstract = "BDN1002";
8+
public const string BenchmarkRunner_Run_TypeArgumentClassMustBeUnsealed = "BDN1003";
89
public const string General_BenchmarkClass_MethodMustBePublic = "BDN1100";
910
public const string General_BenchmarkClass_MethodMustBeNonGeneric = "BDN1101";
10-
public const string General_BenchmarkClass_ClassMustBePublic = "BDN1102";
11-
public const string General_BenchmarkClass_ClassMustBeNonStatic = "BDN1103";
12-
public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract = "BDN1104";
13-
public const string General_BenchmarkClass_GenericClassMustBeAbstractOrAnnotatedWithAGenericTypeArgumentsAttribute = "BDN1105";
14-
public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric = "BDN1106";
15-
public const string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount = "BDN1107";
16-
public const string General_BenchmarkClass_OnlyOneMethodCanBeBaseline = "BDN1108";
11+
public const string General_BenchmarkClass_ClassMustBeNonStatic = "BDN1102";
12+
public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeNonAbstract = "BDN1103";
13+
public const string General_BenchmarkClass_GenericClassMustBeAbstractOrAnnotatedWithAGenericTypeArgumentsAttribute = "BDN1104";
14+
public const string General_BenchmarkClass_ClassWithGenericTypeArgumentsAttributeMustBeGeneric = "BDN1105";
15+
public const string General_BenchmarkClass_GenericTypeArgumentsAttributeMustHaveMatchingTypeParameterCount = "BDN1106";
16+
public const string General_BenchmarkClass_OnlyOneMethodCanBeBaseline = "BDN1107";
1717
public const string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnField = "BDN1200";
1818
public const string Attributes_GeneralParameterAttributes_MutuallyExclusiveOnProperty = "BDN1201";
1919
public const string Attributes_GeneralParameterAttributes_FieldMustBePublic = "BDN1202";

src/BenchmarkDotNet.Analyzers/General/BenchmarkClassAnalyzer.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ public class BenchmarkClassAnalyzer : DiagnosticAnalyzer
2727
isEnabledByDefault: true,
2828
description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_MethodMustBeNonGeneric_Description)));
2929

30-
internal static readonly DiagnosticDescriptor ClassMustBePublicRule = new DiagnosticDescriptor(DiagnosticIds.General_BenchmarkClass_ClassMustBePublic,
31-
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBePublic_Title)),
32-
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBePublic_MessageFormat)),
33-
"Usage",
34-
DiagnosticSeverity.Error,
35-
isEnabledByDefault: true,
36-
description: AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBePublic_Description)));
37-
3830
internal static readonly DiagnosticDescriptor ClassMustBeNonStaticRule = new DiagnosticDescriptor(DiagnosticIds.General_BenchmarkClass_ClassMustBeNonStatic,
3931
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBeNonStatic_Title)),
4032
AnalyzerHelper.GetResourceString(nameof(BenchmarkDotNetAnalyzerResources.General_BenchmarkClass_ClassMustBeNonStatic_MessageFormat)),
@@ -85,7 +77,6 @@ public class BenchmarkClassAnalyzer : DiagnosticAnalyzer
8577
[
8678
MethodMustBePublicRule,
8779
MethodMustBeNonGenericRule,
88-
ClassMustBePublicRule,
8980
ClassMustBeNonStaticRule,
9081
ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule,
9182
GenericClassMustBeAbstractOrAnnotatedWithAGenericTypeArgumentsAttributeRule,
@@ -152,17 +143,12 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
152143
return;
153144
}
154145

155-
var classIsPublic = false;
156146
var classStaticModifier = null as SyntaxToken?;
157147
var classAbstractModifier = null as SyntaxToken?;
158148

159149
foreach (var modifier in classDeclarationSyntax.Modifiers)
160150
{
161-
if (modifier.IsKind(SyntaxKind.PublicKeyword))
162-
{
163-
classIsPublic = true;
164-
}
165-
else if (modifier.IsKind(SyntaxKind.StaticKeyword))
151+
if (modifier.IsKind(SyntaxKind.StaticKeyword))
166152
{
167153
classStaticModifier = modifier;
168154
}
@@ -201,11 +187,6 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
201187
}
202188
}
203189

204-
if (!classIsPublic)
205-
{
206-
context.ReportDiagnostic(Diagnostic.Create(ClassMustBePublicRule, classDeclarationSyntax.Identifier.GetLocation(), classDeclarationSyntax.Identifier.ToString()));
207-
}
208-
209190
if (classAbstractModifier.HasValue && genericTypeArgumentsAttributes.Length > 0)
210191
{
211192
context.ReportDiagnostic(Diagnostic.Create(ClassWithGenericTypeArgumentsAttributeMustBeNonAbstractRule, classAbstractModifier.Value.GetLocation(), classDeclarationSyntax.Identifier.ToString()));

0 commit comments

Comments
 (0)