Having previously written aUse the Fixer to help add header annotation text, today using Roslyn's code fixer for the asynchronous return method normalization feature
Implementation Analyzer
First you need to implement the analyzer, using theRegisterSyntaxNodeAction
, analyze allThe syntactic type of the
[DiagnosticAnalyzer()]
public class AsyncMethodNameAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "GEN051";
private static readonly LocalizableString Title = "Change the asynchronous method name to start withAsyncwind up";
private static readonly LocalizableString MessageFormat = "Change the asynchronous method name to start withAsyncwind up";
private static readonly LocalizableString Description = "Change the asynchronous method name to start withAsyncwind up.";
private const string Category = "Documentation";
private static readonly DiagnosticDescriptor Rule = new(
DiagnosticId, Title, MessageFormat, Category,
, isEnabledByDefault: true, description: Description);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [Rule];
public override void Initialize(AnalysisContext context)
{
if (context is null)
return;
();
();
(AnalyzeNode, );
}
// Asynchronous method names should begin withAsyncwind up
private const string AsyncSuffix = "Async";
private static void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var methodDeclaration = (MethodDeclarationSyntax);
//If the method containsasyncThe case for modification
if (())
{
if (!(AsyncSuffix, ))
{
var diagnostic = (Rule, (), );
(diagnostic);
}
}
var returnType = ;
//If the return type isTaskorTask<T>,orValueTask<T>,ValueTask then the method name should start withAsyncwind up
// Determine if the return type is Task maybe ValueTask
if (returnType is IdentifierNameSyntax identifierName)
{
if ( == "Task" || == "ValueTask")
{
if (!(AsyncSuffix, ))
{
var diagnostic = (Rule, (), );
(diagnostic);
}
}
}
else if (returnType is GenericNameSyntax genericName && ( == "Task" || == "ValueTask"))
{
if (!(AsyncSuffix, ))
{
var diagnostic = (Rule, (), );
(diagnostic);
}
}
}
}
existInitialize
method, a syntax node operation is registered to handle theMethodDeclarationSyntax
nodes, the main consideration is whether the methodasync
keyword annotation, or whether the returned type is aTask
orValueTask
If these conditions are met then the method name is determined.whether or not
Async
End. If such a problem exists then create a diagnostic and report it.
Implementing the Fixer
[ExportCodeFixProvider(, Name = nameof(AsyncMethodNameCodeFixProvider))]
[Shared]
internal class AsyncMethodNameCodeFixProvider : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds => [];
public sealed override FixAllProvider GetFixAllProvider() =>
;
private const string Title = "Change the asynchronous method name to start withAsyncwind up";
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = [0];
var diagnosticSpan = ;
(
(
title: Title,
createChangedDocument:
c =>
FixDocumentAsync(, diagnostic, c),
equivalenceKey: Title),
diagnostic);
return ;
}
private const string AsyncSuffix = "Async";
private static async Task<Document> FixDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken c)
{
var root = await (c).ConfigureAwait(false);
if (root == null)
return document;
var node = ();
var methodDeclaration = (MethodDeclarationSyntax)node;
var newName = $"{}{AsyncSuffix}";
var newRoot = (methodDeclaration, ((newName)));
return (newRoot);
}
}
The implementation of the restorer is much simpler, and we use the diagnostic information and theDocument
You can then locate the problematic method itself, and use theWithIdentifier
cap (a poem)Just fix the method name to the correct value and return the fixed Document!
Preview effect
Finally, let's take a look at the results
Warning messages returned at compile time
Prompts generated when editing a document
Click on the tip to fix the code problem
ultimate
In fact, this belongs to the code habits or code style issues, personally recommended asynchronous methods or add a suffix, after all, with this specification we look at the method will be able to know that this is an asynchronous method 😃
Finally you can use the nuget package I posted to experience.
dotnet add package
I posted the source code to GitHub, welcome to star!/vipwan/