2016-12-01 67 views
6

C# koşullu derleme deyimini Roslyn kullanarak nasıl ayrıştırırım.Ayrıştırma # # Koşullu Derleme ifadeleri roslyn

Aşağıdaki kodda, Roslyn'in Koşullu derleme bildirimi düğümünü vermesini istiyorum.

public abstract class TestClass 
{ 
    public int Get() 
    { 
    #if DEBUG 
     return 1; 
    #else 
     return 2; 
    #endif 
    } 
} 

Ben SyntaxTree koşullu derleme düğümünü alamadım ve ne de ben } arasında LeadingTrivia olsun ne } ait LeadingTrivia veya {

ait TrailingTrivia parçasıdır "\t\t#endif\r\n\t\t" olup { ait TrailingTrivia "\r\n" olan koşullu derleme ifadesi değil.

Birisi beni doğru yöne yönlendirebilir mi? Bunu yapabileceğini,

public override SyntaxNode VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node) 
{ 
} 

public override SyntaxNode VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node) 
{ 
} 

public override SyntaxNode VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node) 
{ 
} 

değil ziyaretçiler aracılığıyla bu olsun istiyorsanız:: Eğer ziyaretçi (CSharpSyntaxRewriter \ Walker) üzerinden düğümleri ayrıştırmak Eğer

+0

olmayan bir Roslyn çözümü düşünmeye hazırız, bunu yapabilecek Bu sürecin son derece basit olduğunu açıklayın. –

+0

@ ira-baxter, roslyn specificc olmak zorunda – adeel41

cevap

2

geçersiz kılmak gerekir

node.DescendantNodesAndSelf().OfType<ConditionalDirectiveTriviaSyntax>(); 

Koşulunuz için Roslyn'in nasıl oluştuğunu görmek için here'a bakabilirsiniz.

Güncelleme

Çünkü onun değil Node elbette burada biraz karışık bir gerçekten onun tür kontrol etti ve. Düğüm yalnızca return 2 veya #define DEBUG değerini return 1 yazıyorsa.

// First get the relevant method (or any other parent block depending in the case) 
var method = root.DescendantNodes().OfType<MethodDeclarationSyntax>().First(); 

// Then, you can write method similar to this 
static SyntaxTrivia GetConditionalDirectiveTrivia(SyntaxNode node, SyntaxKind kind) 
{ 
    foreach (SyntaxNode syntaxNode in node.DescendantNodes()) 
    { 
     var trivia = syntaxNode.GetLeadingTrivia().FirstOrDefault(t => t.Kind() == kind); 
     if (trivia != default(SyntaxTrivia)) 
      return trivia; 
     GetConditionalDirectiveTrivia(syntaxNode, kind); 
    } 
    return default(SyntaxTrivia); 
} 

Ve böyle diyoruz: Sen olmadan fazla yolla bulabilirsiniz

GetConditionalDirectiveTrivia(method, SyntaxKind.IfDirectiveTrivia); 

Yani, eğer yönteminin içine koşullu yönerge böyle bir şey yapabileceği var Nazik ama bence yeterince iyi.

Not: Bu sadece bir örnektir. Burada sadece ilk trivia'ya geri dönüyorum.

Gerçek kodunuzda, örneğin AllTriviaOfKind veya gereksinimlerinize uygun başka bir şey elde etmek için daha zarif bir çözüm (belki bir uzantı yöntemi bile) yazabilirsiniz. Ayrıca, trivia'nın kendisi sizin için işe yaramazsa, neye ihtiyacınız olursa olsun, belirteç trivia'yı veya ana düğümü döndürebilirsiniz.

Umarım yardım eder.

+0

Metod düğümünde DescendantNodesAndSelf'ı aramayı denedim, ancak ConditionalDirectiveTriviaSyntax'ı listede görmüyorum, bunun yerine bir BlockSyntax (çok genel) olduğunu görmüyorum – adeel41

+0

@ adeel41 ' BlockSyntax' tüm yöntem gövdesinin ebeveyni. Bu blok içerisinde ifadeler bulacaksınız ve ihtiyacınız olanı bulacaksınız. Eğer orijinal düğümünüz 'MethodDeclerationSyntax' ise, ne istediğinizi bulmak için derinlere inmeniz gerekir. –

+0

@ adeel41 Şimdi telefonumdan yazıyorum .. Cevabımı yakında güncelleyebilir ve tam olarak nasıl yapabildiğinizi gösterebilirim (eğer gerekiyorsa) –

2

Ben SyntaxTree koşullu derleme düğümünü alamadım ve ne de Aslında {

ait } ait LeadingTrivia veya TrailingTrivia parçasıdır, bu return 2; içinde return anahtar kelimenin LeadingTrivia içinde.return için kurşun önemsiz geçerli:

  • IfDirectiveTrivia (#if DEBUG)
  • DisableTextTrivia (return 1;)
  • ElseDirectiveTrivia (#else)
+0

Bana bu bilgiyi nasıl bulacağına dair bazı bilgiler verdiğiniz için teşekkür ederim, ancak bu şekilde yapacağımdan emin değilim çünkü çok fazla ayrıştırmam gerekiyor. – adeel41