@@ -358,6 +358,7 @@ private static void CheckNoThrowsOnFullPropertyDecl(SyntaxNodeAnalysisContext co
358358 }
359359 }
360360
361+ // Legacy redundancy check
361362 private void AnalyzeTryStatement ( SyntaxNodeAnalysisContext context )
362363 {
363364 var tryStatement = context . Node as TryStatementSyntax ;
@@ -367,47 +368,57 @@ private void AnalyzeTryStatement(SyntaxNodeAnalysisContext context)
367368
368369 var settings = GetAnalyzerSettings ( context . Options ) ;
369370
370- var semanticModel = context . SemanticModel ;
371-
372- // Check for redundant typed catch clauses
373- foreach ( var catchClause in tryStatement . Catches )
371+ if ( ! settings . IsControlFlowAnalysisEnabled && settings . IsLegacyRedundancyChecksEnabled )
374372 {
375- if ( catchClause . Declaration ? . Type is null )
376- {
377- var thrownExceptions = CollectUnhandledExceptions ( context , tryStatement . Block , settings ) ;
373+ var semanticModel = context . SemanticModel ;
378374
379- if ( thrownExceptions . Count > 0 )
380- continue ;
375+ var thrownExceptions = CollectUnhandledExceptions ( context , tryStatement . Block , settings ) ;
381376
382- // Report redundant catch clause
383- /*var diagnostic = Diagnostic.Create(
384- RuleRedundantCatchAllClause,
385- catchClause.CatchKeyword.GetLocation());
377+ HashSet < INamespaceOrTypeSymbol > unhandledExceptions = new HashSet < INamespaceOrTypeSymbol > ( thrownExceptions , SymbolEqualityComparer . Default ) ;
386378
387- context.ReportDiagnostic(diagnostic);*/
388- }
389- else
379+ // Check for redundant typed catch clauses
380+ foreach ( var catchClause in tryStatement . Catches )
390381 {
391- var catchType = semanticModel . GetTypeInfo ( catchClause . Declaration . Type ) . Type as INamedTypeSymbol ;
392- if ( catchType is null )
393- continue ;
382+ if ( catchClause . Declaration ? . Type is null )
383+ {
384+ if ( unhandledExceptions . Count > 0 )
385+ continue ;
394386
395- var thrownExceptions = CollectUnhandledExceptions ( context , tryStatement . Block , settings ) ;
387+ unhandledExceptions . Clear ( ) ;
396388
397- // Check if any thrown exception matches or derives from this catch type
398- bool isRelevant = thrownExceptions . OfType < INamedTypeSymbol > ( ) . Any ( thrown =>
399- thrown . Equals ( catchType , SymbolEqualityComparer . Default ) ||
400- thrown . InheritsFrom ( catchType ) ) ;
389+ // Report redundant catch clause
390+ var diagnostic = Diagnostic . Create (
391+ RuleRedundantCatchAllClause ,
392+ catchClause . CatchKeyword . GetLocation ( ) ) ;
401393
402- if ( ! isRelevant )
394+ context . ReportDiagnostic ( diagnostic ) ;
395+ }
396+ else
403397 {
404- // Report redundant catch clause
405- /*var diagnostic = Diagnostic.Create(
406- RuleRedundantTypedCatchClause,
407- catchClause.Declaration.Type.GetLocation(),
408- catchType.Name);
398+ var catchType = semanticModel . GetTypeInfo ( catchClause . Declaration . Type ) . Type as INamedTypeSymbol ;
399+ if ( catchType is null )
400+ continue ;
409401
410- context.ReportDiagnostic(diagnostic);*/
402+ // Update unhandled set
403+ unhandledExceptions . RemoveWhere ( thrown =>
404+ SymbolEqualityComparer . Default . Equals ( thrown , catchType ) ||
405+ ( thrown is INamedTypeSymbol named && named . InheritsFrom ( catchType ) ) ) ;
406+
407+ // Check if any thrown exception matches or derives from this catch type
408+ bool isRelevant = thrownExceptions . OfType < INamedTypeSymbol > ( ) . Any ( thrown =>
409+ thrown . Equals ( catchType , SymbolEqualityComparer . Default ) ||
410+ thrown . InheritsFrom ( catchType ) ) ;
411+
412+ if ( ! isRelevant )
413+ {
414+ // Report redundant catch clause
415+ var diagnostic = Diagnostic . Create (
416+ RuleRedundantTypedCatchClause ,
417+ catchClause . Declaration . Type . GetLocation ( ) ,
418+ catchType . Name ) ;
419+
420+ context . ReportDiagnostic ( diagnostic ) ;
421+ }
411422 }
412423 }
413424 }
0 commit comments