Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect c# 6 features with Roslyn

Tags:

c#

roslyn

Is there a way to detect a c# 6 feature with a roslyn diagnostic analyzer?

I have a solution that links in some files from a project that cannot use c#6 features, so I want to make that an error just for those files. To be clear - I cannot set the whole project to c#5, only some files are off limits.

I can try and catch specific features, but it's cumbersome and was wondering if there is a faster way?

like image 838
Robert Ivanc Avatar asked Oct 18 '22 09:10

Robert Ivanc


2 Answers

You can use this Walker for detecting C# 6 syntax features:

public class CSharp6FeaturesWalker : CSharpSyntaxWalker
{
    public bool CSharp6Features { get; private set; }

    public CSharp6FeatureWalker()
    {
    }

    public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
    {
        if (node.ExpressionBody != null)
        {
            CSharp6Features = true;
        }
        else if (node.Initializer != null)
        {
            CSharp6Features = true;
        }
        base.VisitPropertyDeclaration(node);
    }

    public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        if (node.ExpressionBody != null)
        {
            CSharp6Features = true;
        }
        base.VisitMethodDeclaration(node);
    }

    public override void VisitOperatorDeclaration(OperatorDeclarationSyntax node)
    {
        if (node.ExpressionBody != null)
        {
            CSharp6Features = true;
        }
        base.VisitOperatorDeclaration(node);
    }

    public override void VisitConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax node)
    {
        if (node.ExpressionBody != null)
        {
            CSharp6Features = true;
        }
        base.VisitConversionOperatorDeclaration(node);
    }

    public override void VisitIndexerDeclaration(IndexerDeclarationSyntax node)
    {
        if (node.ExpressionBody != null)
        {
            CSharp6Features = true;
        }
        base.VisitIndexerDeclaration(node);
    }

    public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node)
    {
        CSharp6Features = true;
        base.VisitConditionalAccessExpression(node);
    }

    public override void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node)
    {
        CSharp6Features = true;
        base.VisitInterpolatedStringExpression(node);
    }

    public override void VisitCatchFilterClause(CatchFilterClauseSyntax node)
    {
        CSharp6Features = true;
        base.VisitCatchFilterClause(node);
    }
}

Unfortunately it is not possible to detect whether the file written on 6 version or not based only on syntax checks because of some features are content-depended such as nameof operator (it can be both special or usual method)

For testing C# 6 features you can use this file from ANTLR grammars repository.

like image 79
Ivan Kochurkin Avatar answered Oct 21 '22 02:10

Ivan Kochurkin


I believe the best way to go about this is to use the advanced build options. Go to your project properties and select the "Build" tab. On the bottom-right of that tab (you may have to scroll down) you should see an "Advanced" button. Click that and you'll get this dialog:

Advanced Options

As you see, you can change the language level for your particular project to be C# 5.0. Once you do that, and you try to use, say, string interpolation, you'll be prompted with an error:

enter image description here

like image 31
Kirk Woll Avatar answered Oct 21 '22 01:10

Kirk Woll