-
Notifications
You must be signed in to change notification settings - Fork 381
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Analyzer (currently disabled) for target-typed
new
with throw
- Loading branch information
Showing
4 changed files
with
103 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
ExternalProjects/BizHawk.Analyzer/NoTargetTypedThrowAnalyzer.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
namespace BizHawk.Analyzers; | ||
|
||
using System.Collections.Immutable; | ||
|
||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
using Microsoft.CodeAnalysis.Operations; | ||
|
||
[DiagnosticAnalyzer(LanguageNames.CSharp)] | ||
public sealed class NoTargetTypedThrowAnalyzer : DiagnosticAnalyzer | ||
{ | ||
private const string ERR_MSG_IMPLICIT = "Specify `Exception` (or a more precise type) explicitly"; | ||
|
||
private static readonly DiagnosticDescriptor DiagNoTargetTypedThrow = new( | ||
id: "BHI1007", | ||
title: "Don't use target-typed new for throw expressions", | ||
messageFormat: "{0}", | ||
category: "Usage", | ||
defaultSeverity: DiagnosticSeverity.Warning, | ||
isEnabledByDefault: true); | ||
|
||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(DiagNoTargetTypedThrow); | ||
|
||
public override void Initialize(AnalysisContext context) | ||
{ | ||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); | ||
context.EnableConcurrentExecution(); | ||
context.RegisterOperationAction( | ||
oac => | ||
{ | ||
var exceptionOp = ((IThrowOperation) oac.Operation).Exception; | ||
if (exceptionOp is null) return; // re-`throw;` | ||
void Fail(string message) | ||
=> oac.ReportDiagnostic(Diagnostic.Create(DiagNoTargetTypedThrow, exceptionOp.Syntax.GetLocation(), message)); | ||
switch (exceptionOp.Kind) | ||
{ | ||
case OperationKind.ObjectCreation: | ||
case OperationKind.Invocation: | ||
case OperationKind.PropertyReference: | ||
case OperationKind.LocalReference: | ||
return; | ||
case OperationKind.Conversion: | ||
if (((IConversionOperation) exceptionOp).Operand.Syntax | ||
.IsKind(SyntaxKind.ImplicitObjectCreationExpression)) | ||
{ | ||
break; | ||
} | ||
return; | ||
default: | ||
Fail($"Argument to throw expression was of an unexpected kind: {exceptionOp.GetType().FullName}"); | ||
return; | ||
} | ||
Fail(ERR_MSG_IMPLICIT); | ||
}, | ||
OperationKind.Throw); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
ExternalProjects/BizHawk.AnalyzersTests/BizHawk.Analyzer/NoTargetTypedThrowAnalyzerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
namespace BizHawk.Tests.Analyzers; | ||
|
||
using System.Threading.Tasks; | ||
|
||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
|
||
using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier< | ||
BizHawk.Analyzers.NoTargetTypedThrowAnalyzer, | ||
Microsoft.CodeAnalysis.Testing.DefaultVerifier>; | ||
|
||
[TestClass] | ||
public sealed class NoTargetTypedThrowAnalyzerTests | ||
{ | ||
[TestMethod] | ||
public Task CheckMisuseOfXORAssignment() | ||
=> Verify.VerifyAnalyzerAsync(""" | ||
using System; | ||
public static class Cases { | ||
// not present: throwing a local, which is apparently necessary in Win32 interop | ||
private static void V() | ||
=> throw ExceptionHelperProp; | ||
private static void W() | ||
=> throw ExceptionHelperMethod(); | ||
private static void X() { | ||
try { | ||
Z(); | ||
} catch (Exception) { | ||
throw; | ||
} | ||
} | ||
private static void Y() | ||
=> throw new Exception(); | ||
private static void Z() | ||
=> throw new NotImplementedException(); | ||
private static void A() | ||
=> throw {|BHI1007:new()|}; | ||
private static Exception ExceptionHelperMethod() | ||
=> new(); | ||
private static Exception ExceptionHelperProp | ||
=> new(); | ||
} | ||
"""); | ||
} |
Binary file not shown.