Last active
August 29, 2015 14:01
-
-
Save Schandlich/6cefe55a4fc61f9867f6 to your computer and use it in GitHub Desktop.
Async Method Name Checker
This file contains hidden or 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
[ExportCodeFixProvider(DiagnosticAnalyzer.DiagnosticId, LanguageNames.CSharp)] | |
internal class CodeFixProvider : ICodeFixProvider | |
{ | |
public IEnumerable<string> GetFixableDiagnosticIds() | |
{ | |
return new[] { DiagnosticAnalyzer.DiagnosticId }; | |
} | |
public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken) | |
{ | |
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); | |
var diagnosticSpan = diagnostics.First().Location.SourceSpan; | |
var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<MethodDeclarationSyntax>().First(); | |
return new[] { CodeAction.Create("Fix async naming convention error.", c => ChangeNameAsync(document, declaration, c)) }; | |
} | |
private async Task<Solution> ChangeNameAsync(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) | |
{ | |
var identifierToken = methodDeclaration.Identifier; | |
var newName = identifierToken.Text + "Async"; | |
var semanticModel = await document.GetSemanticModelAsync(cancellationToken); | |
var typeSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); | |
var originalSolution = document.Project.Solution; | |
var optionSet = originalSolution.Workspace.GetOptions(); | |
var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, typeSymbol, newName, optionSet, cancellationToken).ConfigureAwait(false); | |
return newSolution; | |
} | |
} |
This file contains hidden or 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
[DiagnosticAnalyzer] | |
[ExportDiagnosticAnalyzer(DiagnosticId, LanguageNames.CSharp)] | |
public class DiagnosticAnalyzer : ISyntaxNodeAnalyzer<SyntaxKind> | |
{ | |
internal const string DiagnosticId = "AsyncMethodNotNamedCorrectly"; | |
internal const string Description = "A method with an async modifier needs to end with \"Async\""; | |
internal static readonly string MessageFormat = "Make sure the name of this method ends with \"Async\"."; | |
internal const string Category = "Async"; | |
internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Description, MessageFormat, Category, DiagnosticSeverity.Warning); | |
public ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics | |
{ | |
get { return ImmutableArray.Create(Rule); } | |
} | |
public ImmutableArray<SyntaxKind> SyntaxKindsOfInterest | |
{ | |
get { return ImmutableArray.Create(SyntaxKind.MethodDeclaration); } | |
} | |
public void AnalyzeNode(SyntaxNode node, SemanticModel semanticModel, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken) | |
{ | |
var method = (MethodDeclarationSyntax)node; | |
if (method.Modifiers.Any(SyntaxKind.AsyncKeyword) | |
&& method.ReturnType as GenericNameSyntax != null | |
&& !method.Identifier.Text.EndsWith("Async") | |
&& method.DescendantNodes().OfType<PrefixUnaryExpressionSyntax>().Any(x => x.IsKind(SyntaxKind.AwaitExpression))) | |
{ | |
addDiagnostic(Diagnostic.Create(Rule, method.Identifier.GetLocation())); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment