@@ -42,7 +42,7 @@ public class ThrowsInPotentiallyAsyncMethodAnalyzer : DiagnosticAnalyzer {
4242 public override ImmutableArray < DiagnosticDescriptor > SupportedDiagnostics => ImmutableArray . Create ( Rule ) ;
4343
4444 private const string AsyncSuffix = "Async" ;
45- private const string DefaultExcludedTypes = "System.ArgumentException System.NotImplementedException" ;
45+ private const string DefaultExcludedBaseTypes = "System.ArgumentException System.NotImplementedException" ;
4646
4747 public override void Initialize ( AnalysisContext context ) {
4848 context . EnableConcurrentExecution ( ) ;
@@ -73,8 +73,10 @@ public override void Analyze() {
7373 }
7474 }
7575
76- private IEnumerable < string > GetExcludedExceptionTypes ( ) {
77- return Context . Options . GetConfig ( Rule , "exclusions" , DefaultExcludedTypes ) . Split ( ) ;
76+ private IEnumerable < ITypeSymbol > GetExcludedExceptionBaseTypes ( ) {
77+ return Context . Options . GetConfig ( Rule , "exclusions" , DefaultExcludedBaseTypes )
78+ . Split ( )
79+ . SelectMany ( SemanticModel . GetTypesByName ) ;
7880 }
7981
8082 private bool IsPotentiallyAsyncMethod ( ) {
@@ -89,24 +91,25 @@ private bool ReturnsTaskObject() {
8991 }
9092
9193 private IEnumerable < SyntaxNode > GetAllThrowsStatementsAndExpressionsInSameActivationFrame ( ) {
92- var excludedExceptionTypes = GetExcludedExceptionTypes ( ) . ToArray ( ) ;
94+ var excludedBaseTypes = GetExcludedExceptionBaseTypes ( ) . ToArray ( ) ;
9395 return Root . DescendantNodesInSameActivationFrame ( )
9496 . WithCancellation ( CancellationToken )
95- . Where ( node => IsThrowsWithoutExcludedType ( node , excludedExceptionTypes ) ) ;
97+ . Where ( node => IsThrowsWithoutExcludedType ( node , excludedBaseTypes ) ) ;
9698 }
9799
98- private bool IsThrowsWithoutExcludedType ( SyntaxNode node , IEnumerable < string > excludedTypes ) {
100+ private bool IsThrowsWithoutExcludedType ( SyntaxNode node , IEnumerable < ITypeSymbol > excludedBaseTypes ) {
101+
99102 return node switch {
100- ThrowStatementSyntax statement => ! IsAnyOfType ( statement . Expression , excludedTypes ) ,
101- ThrowExpressionSyntax expression => ! IsAnyOfType ( expression . Expression , excludedTypes ) ,
103+ ThrowStatementSyntax statement => ! IsAnySubTypeOf ( statement . Expression , excludedBaseTypes ) ,
104+ ThrowExpressionSyntax expression => ! IsAnySubTypeOf ( expression . Expression , excludedBaseTypes ) ,
102105 _ => false
103106 } ;
104107 }
105108
106- private bool IsAnyOfType ( SyntaxNode node , IEnumerable < string > types ) {
109+ private bool IsAnySubTypeOf ( SyntaxNode node , IEnumerable < ITypeSymbol > types ) {
107110 var nodeType = SemanticModel . GetTypeInfo ( node , CancellationToken ) . Type ;
108111 return nodeType != null
109- && types . Any ( type => SemanticModel . IsEqualType ( nodeType , type ) ) ;
112+ && types . Any ( baseType => baseType . IsBaseTypeOf ( nodeType , CancellationToken ) ) ;
110113 }
111114 }
112115 }
0 commit comments