From 9b3cf647d5d8d837ebfb6a755b11300e553f46d3 Mon Sep 17 00:00:00 2001 From: Mario Pistrich Date: Tue, 20 Feb 2024 00:02:42 +0100 Subject: [PATCH] CA1065: Ignore System.Diagnostics.UnreachableException --- ...NotRaiseExceptionsInUnexpectedLocations.cs | 7 +++- ...iseExceptionsInUnexpectedLocationsTests.cs | 42 ++++++++++++++++++- src/Utilities/Compiler/WellKnownTypeNames.cs | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocations.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocations.cs index 7f30c5492f..f2cfa0d1c1 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocations.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocations.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System; using System.Collections.Generic; @@ -67,6 +67,7 @@ public override void Initialize(AnalysisContext context) { Compilation compilation = compilationStartContext.Compilation; INamedTypeSymbol? exceptionType = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemException); + INamedTypeSymbol? unreachableExceptionType = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemDiagnosticsUnreachableException); if (exceptionType == null) { return; @@ -101,7 +102,9 @@ public override void Initialize(AnalysisContext context) } // Get ThrowOperation's ExceptionType - if (throwOperation.GetThrownExceptionType() is INamedTypeSymbol thrownExceptionType && thrownExceptionType.DerivesFrom(exceptionType)) + if (throwOperation.GetThrownExceptionType() is INamedTypeSymbol thrownExceptionType && + thrownExceptionType.DerivesFrom(exceptionType) && + !SymbolEqualityComparer.Default.Equals(thrownExceptionType, unreachableExceptionType)) { // If no exceptions are allowed or if the thrown exceptions is not an allowed one.. if (methodCategory.AllowedExceptions.IsEmpty || !methodCategory.AllowedExceptions.Any(n => thrownExceptionType.IsAssignableTo(n, compilation))) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocationsTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocationsTests.cs index f3e3d540fa..52bb4dc5db 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocationsTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotRaiseExceptionsInUnexpectedLocationsTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -744,6 +744,46 @@ End Class return VerifyVB.VerifyAnalyzerAsync(code); } + [Fact, WorkItem(6001, "https://github.com/dotnet/roslyn-analyzers/issues/6001")] + public Task UnreachableException_NoDiagnostic() + { + const string code = """ + public class ShouldNotViolate + { + static ShouldNotViolate() + { + throw new System.Diagnostics.UnreachableException(); + } + } + """; + + return new VerifyCS.Test + { + TestCode = code, + FixedCode = code, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + + [Fact, WorkItem(6001, "https://github.com/dotnet/roslyn-analyzers/issues/6001")] + public Task VB_UnreachableException_NoDiagnostic() + { + const string code = """ + Public Class ShouldNotViolate + Shared Sub New() + Throw New System.Diagnostics.UnreachableException() + End Sub + End Class + """; + + return new VerifyVB.Test + { + TestCode = code, + FixedCode = code, + ReferenceAssemblies = ReferenceAssemblies.Net.Net70 + }.RunAsync(); + } + #endregion #region Operator tests diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 09f64f1384..b85343f7e6 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -227,6 +227,7 @@ internal static class WellKnownTypeNames public const string SystemDiagnosticsProcessStartInfo = "System.Diagnostics.ProcessStartInfo"; public const string SystemDiagnosticsTraceListener = "System.Diagnostics.TraceListener"; public const string SystemDiagnosticsTracingEventSource = "System.Diagnostics.Tracing.EventSource"; + public const string SystemDiagnosticsUnreachableException = "System.Diagnostics.UnreachableException"; public const string SystemDirectoryDirectoryEntry = "System.DirectoryServices.DirectoryEntry"; public const string SystemDirectoryServicesActiveDirectoryADSearcher = "System.DirectoryServices.ActiveDirectory.ADSearcher"; public const string SystemDirectoryServicesDirectorySearcher = "System.DirectoryServices.DirectorySearcher";