@@ -43,12 +43,13 @@ public class ArgumentsAttributeAnalyzer : DiagnosticAnalyzer
4343 isEnabledByDefault : true ,
4444 description : AnalyzerHelper . GetResourceString ( nameof ( BenchmarkDotNetAnalyzerResources . Attributes_ArgumentsAttribute_MustHaveMatchingValueType_Description ) ) ) ;
4545
46- public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics => ImmutableArray . Create (
47- RequiresBenchmarkAttributeRule ,
48- MethodWithoutAttributeMustHaveNoParametersRule ,
49- MustHaveMatchingValueCountRule ,
50- MustHaveMatchingValueTypeRule
51- ) ;
46+ public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics =>
47+ [
48+ RequiresBenchmarkAttributeRule ,
49+ MethodWithoutAttributeMustHaveNoParametersRule ,
50+ MustHaveMatchingValueCountRule ,
51+ MustHaveMatchingValueTypeRule
52+ ] ;
5253
5354 public override void Initialize ( AnalysisContext analysisContext )
5455 {
@@ -70,12 +71,12 @@ public override void Initialize(AnalysisContext analysisContext)
7071
7172 private static void AnalyzeMethodDeclaration ( SyntaxNodeAnalysisContext context )
7273 {
73- if ( ! ( context . Node is MethodDeclarationSyntax methodDeclarationSyntax ) )
74+ if ( context . Node is not MethodDeclarationSyntax methodDeclarationSyntax )
7475 {
7576 return ;
7677 }
7778
78- var argumentsAttributeTypeSymbol = GetArgumentsAttributeTypeSymbol ( context . Compilation ) ;
79+ var argumentsAttributeTypeSymbol = context . Compilation . GetTypeByMetadataName ( "BenchmarkDotNet.Attributes.ArgumentsAttribute" ) ;
7980 if ( argumentsAttributeTypeSymbol == null )
8081 {
8182 return ;
@@ -104,7 +105,7 @@ private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
104105 return ;
105106 }
106107
107- var methodParameterTypeSymbolsBuilder = ImmutableArray . CreateBuilder < ITypeSymbol > ( methodDeclarationSyntax . ParameterList . Parameters . Count ) ;
108+ var methodParameterTypeSymbolsBuilder = ImmutableArray . CreateBuilder < ITypeSymbol ? > ( methodDeclarationSyntax . ParameterList . Parameters . Count ) ;
108109
109110 foreach ( var parameterSyntax in methodDeclarationSyntax . ParameterList . Parameters )
110111 {
@@ -168,7 +169,7 @@ private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
168169 continue ;
169170 }
170171
171- ReportIfValueTypeMismatchDiagnostic ( i => collectionExpressionSyntax . Elements [ i ] is ExpressionElementSyntax expressionElementSyntax ? expressionElementSyntax . Expression : null ) ;
172+ ReportIfNotImplicitlyConvertibleValueTypeDiagnostic ( i => collectionExpressionSyntax . Elements [ i ] is ExpressionElementSyntax expressionElementSyntax ? expressionElementSyntax . Expression : null ) ;
172173 }
173174
174175 // Array creation expression
@@ -208,7 +209,7 @@ private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
208209 }
209210
210211 // ReSharper disable once PossibleNullReferenceException
211- ReportIfValueTypeMismatchDiagnostic ( i => arrayCreationExpressionSyntax . Initializer . Expressions [ i ] ) ;
212+ ReportIfNotImplicitlyConvertibleValueTypeDiagnostic ( i => arrayCreationExpressionSyntax . Initializer . Expressions [ i ] ) ;
212213 }
213214 }
214215 }
@@ -229,7 +230,7 @@ private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
229230 }
230231
231232 // ReSharper disable once PossibleNullReferenceException
232- ReportIfValueTypeMismatchDiagnostic ( i => argumentsAttributeSyntax . ArgumentList . Arguments [ i ] . Expression ) ;
233+ ReportIfNotImplicitlyConvertibleValueTypeDiagnostic ( i => argumentsAttributeSyntax . ArgumentList . Arguments [ i ] . Expression ) ;
233234 }
234235 else
235236 {
@@ -242,7 +243,7 @@ private static void AnalyzeMethodDeclaration(SyntaxNodeAnalysisContext context)
242243 }
243244
244245 // ReSharper disable once PossibleNullReferenceException
245- ReportIfValueTypeMismatchDiagnostic ( i => argumentsAttributeSyntax . ArgumentList . Arguments [ i ] . Expression ) ;
246+ ReportIfNotImplicitlyConvertibleValueTypeDiagnostic ( i => argumentsAttributeSyntax . ArgumentList . Arguments [ i ] . Expression ) ;
246247 }
247248 }
248249 }
@@ -260,7 +261,7 @@ void ReportMustHaveMatchingValueCountDiagnostic(Location diagnosticLocation, int
260261 valueCount ) ) ;
261262 }
262263
263- void ReportIfValueTypeMismatchDiagnostic ( Func < int , ExpressionSyntax > valueExpressionSyntaxFunc )
264+ void ReportIfNotImplicitlyConvertibleValueTypeDiagnostic ( Func < int , ExpressionSyntax > valueExpressionSyntaxFunc )
264265 {
265266 for ( var i = 0 ; i < methodParameterTypeSymbols . Length ; i ++ )
266267 {
@@ -282,23 +283,35 @@ void ReportIfValueTypeMismatchDiagnostic(Func<int, ExpressionSyntax> valueExpres
282283 var conversionSummary = context . Compilation . ClassifyConversion ( actualValueTypeSymbol , methodParameterTypeSymbol ) ;
283284 if ( ! conversionSummary . IsImplicit )
284285 {
285- ReportMustHaveMatchingValueTypeDiagnostic ( valueExpressionSyntax . GetLocation ( ) ,
286- valueExpressionSyntax . ToString ( ) ,
287- methodParameterTypeSymbol . ToString ( ) ,
288- actualValueTypeSymbol . ToString ( ) ) ;
286+ if ( conversionSummary is { IsExplicit : true , IsEnumeration : false } )
287+ {
288+ var constantValue = context . SemanticModel . GetConstantValue ( valueExpressionSyntax is CastExpressionSyntax castExpressionSyntax ? castExpressionSyntax . Expression : valueExpressionSyntax ) ;
289+ if ( constantValue is { HasValue : true , Value : not null } )
290+ {
291+ if ( AnalyzerHelper . ValueFitsInType ( constantValue . Value , methodParameterTypeSymbol ) )
292+ {
293+ return ;
294+ }
295+ }
296+ }
297+
298+ ReportValueTypeMustBeImplicitlyConvertibleDiagnostic ( valueExpressionSyntax . GetLocation ( ) ,
299+ valueExpressionSyntax . ToString ( ) ,
300+ methodParameterTypeSymbol . ToString ( ) ,
301+ actualValueTypeSymbol . ToString ( ) ) ;
289302 }
290303 }
291304 else
292305 {
293- ReportMustHaveMatchingValueTypeDiagnostic ( valueExpressionSyntax . GetLocation ( ) ,
294- valueExpressionSyntax . ToString ( ) ,
295- methodParameterTypeSymbol . ToString ( ) ) ;
306+ ReportValueTypeMustBeImplicitlyConvertibleDiagnostic ( valueExpressionSyntax . GetLocation ( ) ,
307+ valueExpressionSyntax . ToString ( ) ,
308+ methodParameterTypeSymbol . ToString ( ) ) ;
296309 }
297310 }
298311
299312 return ;
300313
301- void ReportMustHaveMatchingValueTypeDiagnostic ( Location diagnosticLocation , string value , string expectedType , string actualType = null )
314+ void ReportValueTypeMustBeImplicitlyConvertibleDiagnostic ( Location diagnosticLocation , string value , string expectedType , string ? actualType = null )
302315 {
303316 context . ReportDiagnostic ( Diagnostic . Create ( MustHaveMatchingValueTypeRule ,
304317 diagnosticLocation ,
@@ -309,8 +322,6 @@ void ReportMustHaveMatchingValueTypeDiagnostic(Location diagnosticLocation, stri
309322 }
310323 }
311324
312- private static INamedTypeSymbol GetArgumentsAttributeTypeSymbol ( Compilation compilation ) => compilation . GetTypeByMetadataName ( "BenchmarkDotNet.Attributes.ArgumentsAttribute" ) ;
313-
314325 private static int ? IndexOfNamedArgument ( SeparatedSyntaxList < AttributeArgumentSyntax > attributeArguments )
315326 {
316327 var i = 0 ;
0 commit comments