If you want to write an analyzer that checks for certain conditions for a given type, you are going to have to familiarize yourself in working with types in Roslyn. Types returned to you from various Roslyn methods will return to you an object that implements ITypeSymbol. This interface has various methods that can provide you with the information you need to make decisions in your analyzer. You can get types for various nodes in the semantic model by using the SemanticModel.GetTypeInfo and then using either the Type or ConvertedType off of the TypeInfo that is returned. The difference between the Type and ConvertedType is that the ConvertedType is the type after any implicit conversions have been applied. If there are no implicit conversions, then Type and ConvertedType are identical.

There are some types that are special and can be checked by using the SpecialKind enum. For example, if you have an ITypeSymbol and you want to check if it is a string, you could simply do the following.

if (variableTypeInfo.SpecialType == SpecialType.System_String)
{
}

One question that you may have is how to get an ITypeSymbol if it is not defined in the SpecialKind enum. I had the same question and posted it to StackOverflow. I got an answer from Kevin Pilch-Bisson (@Pilchie) which states:

The normal pattern for doing this is to use Compilation.GetTypeByMetadataName(), and then compare that ITypeSymbol with The one you got back from SemanticModel.GetTypeInfo().

Note: Make sure to use .Equals to compare ITypeSymbol instances, as some of them do not guarantee reference identity.

So, if we register a CompilationStartAction, then we can get at a type by simply using the GetTypeByMetadataName method:

var arrayListType = compilationContext.Compilation.GetTypeByMetadataName("System.Collections.ArrayList");

So, now that I have the ArrayList ITypeSymbol, I can now use that to compare to other ITypeSymbol interfaces I get back from the semantic model.

For example, I could have an analyzer that prohibits the usage of ArrayList. I can register a SyntaxNodeAction for all ObjectCreationExpressoin syntax kinds and use the GetTypeInfo method to get the type of the creation and determine if it is an array list.

public override void Initialize(AnalysisContext context)
{
    context.RegisterCompilationStartAction(AnalyzeArrayList);
}

private static void AnalyzeArrayList(CompilationStartAnalysisContext compilationContext)
{
    var arrayListType = compilationContext.Compilation.GetTypeByMetadataName("System.Collections.ArrayList");

    compilationContext.RegisterSyntaxNodeAction(syntaxContext =>
    {
        var variableTypeInfo = syntaxContext.SemanticModel.GetTypeInfo(syntaxContext.Node).Type as INamedTypeSymbol;

        if (variableTypeInfo == null)
            return;

        if (variableTypeInfo.Equals(arrayListType))
        {
            syntaxContext.ReportDiagnostic(Diagnostic.Create(Rule, syntaxContext.Node.GetLocation()));
        }
    }, SyntaxKind.ObjectCreationExpression);
}

As the name implies, the GetTypeByMetadataName uses the metadata name of the type to find the type. One place where this might catch you is when dealing with generics. For example, when working with a dictionary, you might be tempted to try one of the following:

var dictionaryType = compilationContext.Compilation.GetTypeByMetadataName("System.Collections.Generic.Dictionary <string, string>");
var dictionaryType2 = compilationContext.Compilation.GetTypeByMetadataName("System.Collections.Generic.Dictionary <TKey, TValue>");

But the Metadata name for the generic dictionary is Dictionary`2. For generics it is always the name of the type followed by the arity (number of type parameters) that make up the metadata name (e.g. List`1, Tuple`5). For more info, you can read up on type names and arity encoding.

So the correct way to get a generic dictionary is

var dictionaryType2 = compilationContext.Compilation.GetTypeByMetadataName("System.Collections.Generic.Dictionary`2");

If you are still unsure of the correct value to use for the GetTypeByMetadataName method, you can look at the MetadataName property that is available on all objects that implement ISymbol.

As you can see working with types in code analyzers is not too difficult once you know where to look and how to obtain the types you care about.