If you have worked with code analysis tools that analyzed .net code prior to Visual Studio 2015, you know that they sometimes struggled with the async and await keywords. This is because many of the tools worked with the IL generated from your build and struggled with the state machine that is created for Async code. Now that Roslyn analyzers work with the source code instead of the IL, async and await are first class citizens. For example, you could easily write an analyzer to ensure that all async methods contain a suffix of "Async".

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AsyncMethodNameAnalyzer : DiagnosticAnalyzer
{
    public const string DiagnosticId = "AsyncMethodNameAnalyzer";
    internal static readonly LocalizableString Title = "Async method names must end with Async";
    internal static readonly LocalizableString MessageFormat = "'{0}' does not end with Async";
    internal const string Category = "AsyncAnalyzer Category";

    internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, true);

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

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSymbolAction(AsyncMethodValidator, SymbolKind.Method);
    }

    private static void AsyncMethodValidator(SymbolAnalysisContext context)
    {
        var methodSymbol = context.Symbol as IMethodSymbol;
        if (methodSymbol.IsAsync && !methodSymbol.Name.EndsWith("Async"))
        {
            foreach (var location in methodSymbol.Locations)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, location, methodSymbol.Name));
            }
        }
    }
}

As you can see, in the AsyncMethodValidator method, I can simply check the IsAsync property on the method symbol to determine if a method is async. So if you wrote code like the code below, you would receive a diagnostic:

private async Task DoStuff()
{
    await Task.Delay(500);
}

I could also write an analyzer to verify that any method that contains the "Async" suffix is actually an async method. The logic for this is just the inverse for the logic for the AsyncMethodNameAnalyzer:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class DontLieAboutAsyncAnalyzer : DiagnosticAnalyzer
{
    public const string DiagnosticId = "DontLieAboutAsyncAnalyzer";
    internal static readonly LocalizableString Title = "Don't lie about being async.";
    internal static readonly LocalizableString MessageFormat = "'{0}' ends with Async, but is not an async method";
    internal const string Category = "DontLieAboutAsyncAnalyzer Category";

    internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, true);

    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSymbolAction(AsyncMethodValidator, SymbolKind.Method);
    }

    private static void AsyncMethodValidator(SymbolAnalysisContext context)
    {
        var methodSymbol = context.Symbol as IMethodSymbol;
        if (!methodSymbol.IsAsync && methodSymbol.Name.EndsWith("Async"))
        {
            foreach (var location in methodSymbol.Locations)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, location, methodSymbol.Name));
            }
        }
    }
}

Now, if you write code where a method ends in "Async", but it is not async, you will get a diagnostic. For example, the code below will raise a diagnostic:

private void DoStuffAsync()
{

}

Now that the analyzers have access to the source code instead of the IL, it makes working with language features that generate complex IL much easier. As you can see, creating a diagnostic that works with code that leverages async and await is not to different than code that works with any other method in your code.