Roslyn analyzers help to write high quality code in .NET using the Roslyn API and C#. The are like an eslinter in the node.js world.
First of all. This is an analyzer, not a code-fix.
1) Lets create a CancellationTokenAnalyzer.csproj with the following content. (netstandard2.0 is required. We can still use some new C# features by specifying the language version)
<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>netstandard2.0</TargetFramework><LangVersion>preview</LangVersion><Nullable>enable</Nullable><WarningsAsErrors>Nullable</WarningsAsErrors>👇 Required for debugging in Visual Studio<IsRoslynComponent>true</IsRoslynComponent></PropertyGroup><ItemGroup><PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.5.0" /></ItemGroup></Project>
2) Create a file called CancellationTokenArgumentAnalyzer.cs
[DiagnosticAnalyzer(LanguageNames.CSharp)]public class CancellationTokenArgumentAnalyzer : DiagnosticAnalyzer{private static readonly DiagnosticDescriptor _rule = new(id: "CancellationTokenArgumentAnalyzer",title: "Checks missing CancellationToken argument",messageFormat: "Missing CancellationToken argument for '{0}'",category: "CancellationToken",defaultSeverity: DiagnosticSeverity.Warning,isEnabledByDefault: true,description: "Checks missing CancellationToken argument.");public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(_rule);public override void Initialize(AnalysisContext context){context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);context.EnableConcurrentExecution();context.RegisterOperationAction(AnalyzeOperation, OperationKind.Invocation);}private static void AnalyzeOperation(OperationAnalysisContext context){if (context.Operation is not IInvocationOperation invocationOperation){return;}var methodSymbol = invocationOperation.TargetMethod;var arguments = invocationOperation.Arguments;if (methodSymbol.ReturnType.Name is not "Task" or "ValueTask"){return;}if (!arguments.Any(x => x.Value.Type?.Name == "CancellationToken")){var diagnostic = Diagnostic.Create(_rule, invocationOperation.Syntax.GetLocation(), methodSymbol.Name);context.ReportDiagnostic(diagnostic);}}}
3) Add the following line to the consuming MyApplication.csproj.
<Project Sdk="Microsoft.NET.Sdk"><ItemGroup>👇<PackageReference Include="..\CancellationTokenAnalyzer\CancellationTokenAnalyzer.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /></ItemGroup></Project>
4) Compile the consuming MyApplication.csproj
dotnet build
Done! You should now see all warnings about missing CancellationToken's. 😊
Visual Studio (not VS Code) will run analyzers automatically while coding. Unfortunately performance is a huge issue. So we should write analyzers as efficient as possible.