2016-05-20 15 views
5

Czy istnieje sposób wykrywania funkcji C# 6 za pomocą analizatora diagnostycznego Roslyn?Wykryj funkcje C# 6 z Roslyn

Mam rozwiązanie, które łączy w niektórych plikach z projektu, który nie może korzystać z funkcji C# 6, więc chcę zrobić błąd tylko dla tych plików. Aby było jasne - nie mogę ustawić całego projektu na C# 5, tylko niektóre pliki są niedostępne.

Mogę spróbować złapać określone funkcje, ale jest to uciążliwe i zastanawiałem się, czy jest szybszy sposób?

+1

Jako alternatywa, która jest prawdopodobnie znacznie łatwiejsza do wdrożenia: wystarczy uruchomić kompilację przy użyciu kompilatora C# 5 w tym projekcie w ramach procesu budowania. Niezależnie od tego, czy jest to niestandardowe wydarzenie budowania, czy też jest częścią twojego CI. – Rob

+0

@Rob Naprawdę myślę, że to sposób, aby przejść tutaj. –

+0

@Rob Mam tylko kilka plików powiązanych w tym projekcie z innego, te nie powinny korzystać z tych funkcji. Reszta może z nich korzystać. –

Odpowiedz

2

Można korzystać z tej Walker wykrywania C# 6 możliwości składni:

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); 
    } 
} 

Niestety, nie jest możliwe, aby wykryć, czy plik napisany w dniu 6 wersji lub nie opiera się wyłącznie na kontroli składni powodu niektóre funkcje są treści zależało takich jak nameof operatora (może to być zarówno specjalny lub zwykły sposób)

Do testowania funkcji C# 6 można użyć this file z repozytorium gramatyk ANTLR.

+0

dziękuję, wydaje się, że to najlepszy sposób, aby to osiągnąć! –

+0

Już nazwałeś 'nameof()' jako przeszkodę, więc dodałem "using static", "initializers Dictionary", 'czekaj' w blokach 'catch' i' finally', a może coś innego, o czym zapomniałem. Należy zdecydowanie zauważyć, że przedstawione rozwiązanie obejmuje tylko podstawy (choć wprawdzie: są to najczęściej używane).Możesz to rozwinąć także przy większości innych zmian. –

1

Uważam, że najlepszym sposobem na rozwiązanie tego problemu jest użycie zaawansowanych opcji kompilacji. Przejdź do właściwości projektu i wybierz kartę "Kompilacja". W prawym dolnym rogu tej zakładki (być może trzeba przewinąć w dół) powinien pojawić się przycisk "Zaawansowane". Kliknij i że dostaniesz to okno:

Advanced Options

Jak widać, można zmienić poziom językowy dla danego projektu będzie C# 5.0. Gdy to zrobisz, i spróbować użyć, powiedzmy, interpolacja ciąg, zostaniesz poproszony o błędzie:

enter image description here

+0

Sądzę, że nie byłam zbyt jasna (to bardzo dziwny projekt) - tylko niektóre pliki z projektu nie powinny używać funkcji C# 6, a nie całego projektu, więc to nie zadziała. Dzięki za pomoc! –

+0

@RobertIvanc, ale nie rozumiem, dlaczego nie tworzysz osobnego projektu dla tych konkretnych plików. Wygląda na to, że jest to właściwy przypadek użycia do segragacji projektu. –

+1

Tak, wygląda na to, że twoje pytanie brzmi "te konkretne pliki są połączone w inny projekt, który nie może używać C# 6." Następnie zaznaczyć, że inny projekt nie może używać C# 6 ...? –