Skip to content

Commit

Permalink
Merge pull request #2873 from goyzhang/master
Browse files Browse the repository at this point in the history
Add a fixer for CA2200
  • Loading branch information
mavasani authored Sep 30, 2019
2 parents 7d37a2b + 6c0eca6 commit 188af5d
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System.Collections.Immutable;
using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Formatting;

namespace Microsoft.CodeQuality.Analyzers.QualityGuidelines
{
/// <summary>
/// CA2200: Rethrow to preserve stack details
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = RethrowToPreserveStackDetailsAnalyzer.RuleId), Shared]
public sealed class RethrowToPreserveStackDetailsFixer : CodeFixProvider
{
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(RethrowToPreserveStackDetailsAnalyzer.RuleId);

public sealed override FixAllProvider GetFixAllProvider()
{
// See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers'
return WellKnownFixAllProviders.BatchFixer;
}
public async sealed override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var diagnostics = context.Diagnostics;

var nodeToReplace = root.FindNode(context.Span);
if (nodeToReplace == null)
{
return;
}
// Register a code action that will invoke the fix.
context.RegisterCodeFix(
CodeAction.Create(
title: MicrosoftCodeQualityAnalyzersResources.RethrowToPreserveStackDetailsTitle,
createChangedDocument: c => MakeThrowAsync(context.Document, nodeToReplace, c),
equivalenceKey: nameof(RethrowToPreserveStackDetailsFixer)),
diagnostics);
}

private async Task<Document> MakeThrowAsync(Document document, SyntaxNode nodeToReplace, CancellationToken cancellationToken)
{
var formattednewLocal = SyntaxGenerator.GetGenerator(document).ThrowStatement()
.WithLeadingTrivia(nodeToReplace.GetLeadingTrivia())
.WithTrailingTrivia(nodeToReplace.GetTrailingTrivia())
.WithAdditionalAnnotations(Formatter.Annotation);

var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var newRoot = oldRoot.ReplaceNode(nodeToReplace, formattednewLocal);

return document.WithSyntaxRoot(newRoot);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
Microsoft.CodeQuality.CSharp.Analyzers.QualityGuidelines.CSharpRethrowToPreserveStackDetailsAnalyzer,
Microsoft.CodeQuality.Analyzers.QualityGuidelines.RethrowToPreserveStackDetailsFixer>;
using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier<
Microsoft.CodeQuality.VisualBasic.Analyzers.QualityGuidelines.BasicRethrowToPreserveStackDetailsAnalyzer,
Microsoft.CodeQuality.Analyzers.QualityGuidelines.RethrowToPreserveStackDetailsFixer>;

namespace Microsoft.CodeQuality.Analyzers.UnitTests.QualityGuidelines
{
public class RethrowToPreserveStackDetailsTests
{
[Fact]
public async Task TestCSharp_RethrowExplicitlyToThrowImplicitly()
{
await VerifyCS.VerifyCodeFixAsync(@"
using System;
class Program
{
void CatchAndRethrowExplicitly()
{
try
{
ThrowException();
}
catch (ArithmeticException e)
{
throw e; //Some comments
}
}
void ThrowException()
{
throw new ArithmeticException();
}
}", new DiagnosticResult(CSharp.Analyzers.QualityGuidelines.CSharpRethrowToPreserveStackDetailsAnalyzer.Rule).WithLocation(14, 13),
@"
using System;
class Program
{
void CatchAndRethrowExplicitly()
{
try
{
ThrowException();
}
catch (ArithmeticException e)
{
throw; //Some comments
}
}
void ThrowException()
{
throw new ArithmeticException();
}
}");
}
[Fact]
public async Task TestBasic_RethrowExplicitlyToThrowImplicitly()
{
await VerifyVB.VerifyCodeFixAsync(@"
Imports System
Class Program
Sub CatchAndRethrowExplicitly()
Try
Throw New ArithmeticException()
Catch e As ArithmeticException
Throw e 'Some comment
End Try
End Sub
End Class
", new DiagnosticResult(VisualBasic.Analyzers.QualityGuidelines.BasicRethrowToPreserveStackDetailsAnalyzer.Rule).WithLocation(8, 13),
@"
Imports System
Class Program
Sub CatchAndRethrowExplicitly()
Try
Throw New ArithmeticException()
Catch e As ArithmeticException
Throw 'Some comment
End Try
End Sub
End Class
"
);
}
}
}


0 comments on commit 188af5d

Please sign in to comment.