@@ -79,36 +79,56 @@ private static void Analyze(SyntaxNodeAnalysisContext context)
7979 return ;
8080 }
8181
82- if ( memberAccessExpression . Expression is not IdentifierNameSyntax typeIdentifier )
82+ if ( memberAccessExpression . Expression is not IdentifierNameSyntax identifierNameSyntax )
8383 {
8484 return ;
8585 }
8686
87- var classMemberAccessSymbol = context . SemanticModel . GetTypeInfo ( typeIdentifier ) . Type ;
88- if ( classMemberAccessSymbol is null || ! classMemberAccessSymbol . Equals ( context . Compilation . GetTypeByMetadataName ( "BenchmarkDotNet.Running.BenchmarkRunner" ) , SymbolEqualityComparer . Default ) )
87+ var classMemberAccessTypeSymbol = context . SemanticModel . GetTypeInfo ( identifierNameSyntax ) . Type ;
88+ if ( classMemberAccessTypeSymbol is null
89+ || classMemberAccessTypeSymbol . TypeKind == TypeKind . Error
90+ || ! classMemberAccessTypeSymbol . Equals ( context . Compilation . GetTypeByMetadataName ( "BenchmarkDotNet.Running.BenchmarkRunner" ) , SymbolEqualityComparer . Default ) )
8991 {
9092 return ;
9193 }
9294
93- // TODO: Support Type overloads that use the typeof() expression
94-
95- if ( memberAccessExpression . Name is not GenericNameSyntax genericMethod )
95+ if ( memberAccessExpression . Name . Identifier . ValueText != "Run" )
9696 {
9797 return ;
9898 }
9999
100- if ( genericMethod . Identifier . ValueText != "Run" )
100+ INamedTypeSymbol ? benchmarkClassTypeSymbol ;
101+ Location ? diagnosticLocation ;
102+
103+ if ( memberAccessExpression . Name is GenericNameSyntax genericMethod )
101104 {
102- return ;
103- }
105+ if ( genericMethod . TypeArgumentList . Arguments . Count != 1 )
106+ {
107+ return ;
108+ }
104109
105- if ( genericMethod . TypeArgumentList . Arguments . Count != 1 )
110+ diagnosticLocation = Location . Create ( context . FilterTree , genericMethod . TypeArgumentList . Arguments . Span ) ;
111+ benchmarkClassTypeSymbol = context . SemanticModel . GetTypeInfo ( genericMethod . TypeArgumentList . Arguments [ 0 ] ) . Type as INamedTypeSymbol ;
112+ }
113+ else
106114 {
107- return ;
115+ if ( invocationExpression . ArgumentList . Arguments . Count == 0 )
116+ {
117+ return ;
118+ }
119+
120+ // TODO: Support analyzing an array of typeof() expressions
121+ if ( invocationExpression . ArgumentList . Arguments [ 0 ] . Expression is not TypeOfExpressionSyntax typeOfExpression )
122+ {
123+ return ;
124+ }
125+
126+ diagnosticLocation = typeOfExpression . Type . GetLocation ( ) ;
127+ benchmarkClassTypeSymbol = context . SemanticModel . GetTypeInfo ( typeOfExpression . Type ) . Type as INamedTypeSymbol ;
128+
108129 }
109130
110- var benchmarkClassTypeSymbol = context . SemanticModel . GetTypeInfo ( genericMethod . TypeArgumentList . Arguments [ 0 ] ) . Type ;
111- if ( benchmarkClassTypeSymbol == null || benchmarkClassTypeSymbol . TypeKind == TypeKind . Error )
131+ if ( benchmarkClassTypeSymbol == null || benchmarkClassTypeSymbol . TypeKind == TypeKind . Error || ( benchmarkClassTypeSymbol . IsGenericType && ! benchmarkClassTypeSymbol . IsUnboundGenericType ) )
112132 {
113133 return ;
114134 }
@@ -166,15 +186,15 @@ bool HasBenchmarkAttribute()
166186 }
167187 }
168188
169- baseType = baseType . BaseType ;
189+ baseType = baseType . OriginalDefinition . BaseType ;
170190 }
171191
172192 return false ;
173193 }
174194
175195 void ReportDiagnostic ( DiagnosticDescriptor diagnosticDescriptor )
176196 {
177- context . ReportDiagnostic ( Diagnostic . Create ( diagnosticDescriptor , Location . Create ( context . FilterTree , genericMethod . TypeArgumentList . Arguments . Span ) , benchmarkClassTypeSymbol . Name ) ) ;
197+ context . ReportDiagnostic ( Diagnostic . Create ( diagnosticDescriptor , diagnosticLocation , AnalyzerHelper . NormalizeTypeName ( benchmarkClassTypeSymbol ) ) ) ;
178198 }
179199 }
180200 }
0 commit comments