Fun with Code Diagnostic Analyzers

A few days ago I posted an article detailing how to construct a code diagnostic analyzer and code fix provider to detect if..else statements that simply assign a variable or return a value and replace the statements with a conditional operator. You know, the kind of things that code diagnostic analyzers and code fix providers are intended for. As I was developing those components I got to thinking about what kind of fun I could have while abusing the feature. More specifically, I wondered whether could I construct a code diagnostic analyzer such that it would highlight every line of C# code as a warning and recommend using F# instead.

It turns out, it’s actually really easy. The trick is to register a syntax tree action rather than a syntax node action and always report the diagnostic rule at the tree’s root location. For an extra bit of fun, I also set the diagnostic rule’s help link to fsharp.org so that clicking the link in the error list directs the user to that site.

Here’s the analyzer’s code listing in its entirety:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using System.Collections.Immutable;

namespace UseFSharpAnalyzer
{
    [DiagnosticAnalyzer(LanguageNames.CSharp)]
    public class UseFSharpAnalyzerAnalyzer : DiagnosticAnalyzer
    {
        internal static DiagnosticDescriptor Rule =
            new DiagnosticDescriptor(
                "UseFSharpAnalyzer",
                "Use F#",
                "You're using C#; Try F# instead!",
                "Language Choice",
                DiagnosticSeverity.Warning,
                isEnabledByDefault: true,
                helpLink: "http://fsharp.org");

        public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }

        public override void Initialize(AnalysisContext context)
        {
            context.RegisterSyntaxTreeAction(AnalyzeTree);
        }

        private static void AnalyzeTree(SyntaxTreeAnalysisContext context)
        {
            var rootLocation = context.Tree.GetRoot().GetLocation();
            var diag = Diagnostic.Create(Rule, rootLocation);

            context.ReportDiagnostic(diag);
        }
    }
}

When applied to a C# file, the result is as follows:

Use F# Analyzer

This is clearly an example of what not to do with code analyzers but it was fun to put together and see the result nonetheless. If you’ve thought of any other entertaining uses for code analyzers, I’d love to hear about them!

Advertisements

One comment

Comments are closed.