2016-12-01 10 views
6

में सशर्त संकलन विवरण, मैं Roslyn का उपयोग कर सी # सशर्त संकलन विवरण कैसे पार्स कर सकता हूं।पार्सिंग सी # रोसलीन

निम्नलिखित कोड में, मैं रोज़लिन को सशर्त संकलन कथन नोड देना चाहता हूं।

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

मैं SyntaxTree में सशर्त संकलन नोड नहीं मिलता है और न ही यह } की LeadingTrivia या {

की TrailingTrivia का हिस्सा है मैं } की LeadingTrivia में क्या मिलता "\t\t#endif\r\n\t\t" है और { की TrailingTrivia "\r\n" है जो पूर्ण सशर्त संकलन कथन नहीं है।

क्या कोई मुझे सही दिशा में इंगित कर सकता है? आप ऐसा कर सकते

public override SyntaxNode VisitIfDirectiveTrivia(IfDirectiveTriviaSyntax node) 
{ 
} 

public override SyntaxNode VisitElseDirectiveTrivia(ElseDirectiveTriviaSyntax node) 
{ 
} 

public override SyntaxNode VisitEndIfDirectiveTrivia(EndIfDirectiveTriviaSyntax node) 
{ 
} 

आप आगंतुकों के माध्यम से नहीं इस प्राप्त करना चाहते हैं,:

+0

आप एक गैर रोसलिन समाधान पर विचार करने को तैयार हैं, तो मैं यह कर सकते हैं एक का वर्णन करें जहां यह प्रक्रिया बेहद सरल है। –

+0

@ ira-baxter यह roslyn निर्दिष्ट है – adeel41

उत्तर

2

आप आगंतुक (CSharpSyntaxRewriter \ वॉकर) के माध्यम से नोड्स पार्स यदि आप ओवरराइड करने के लिए की जरूरत है

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

Rosaln आपके सशर्त के लिए उत्पन्न करने के लिए आप here देख सकते हैं।

अद्यतन

मैं क्योंकि इसके Node निश्चित रूप से नहीं यहां जटिल की यह जाँच, और वास्तव में अपनी तरह,। नोड सिर्फ return 2 है या यदि आप #define DEBUG लिखते हैं तो return 1

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

और यह इस तरह फोन:

GetConditionalDirectiveTrivia(method, SyntaxKind.IfDirectiveTrivia); 

आप बिना अधिक तरीकों से इसे पा सकते हैं

तो, मामले में आप विधि के अंदर सशर्त निर्देश आप कुछ इस तरह कर सकते हैं कि है दयालु लेकिन मुझे लगता है कि यह काफी अच्छा है।

नोट, यह सिर्फ एक उदाहरण है। मैं यहां केवल पहली मामूली वापसी करता हूं।

अपने असली कोड में, उदाहरण के लिए AllTriviaOfKind या अपनी आवश्यकताओं के अनुसार कुछ और प्राप्त करने के लिए आप अधिक सुरुचिपूर्ण समाधान (शायद एक विस्तार विधि भी) लिख सकते हैं। इसके अलावा, आप टोकन ट्रिविया या पैरेंट नोड वापस कर सकते हैं, अगर ट्रिविया स्वयं आपके लिए बेकार है, जो भी आप चाहते हैं।

मुझे इसकी मदद की उम्मीद है।

+0

मैं आगंतुकों का उपयोग नहीं कर रहा हूं इसलिए मैंने DescendantNodes और स्वयं को विधि नोड पर कॉल करने का प्रयास किया लेकिन मुझे सूची में सशर्त डायरेक्टिव ट्रिविया सिंटैक्स नहीं दिख रहा है, इसके बजाय एक ब्लॉकसिंटाक्स (जो बहुत सामान्य है) – adeel41

+0

@ adeel41 ' BlockSyntax' आपके सभी विधि निकाय का अभिभावक है। इस ब्लॉक के भीतर आपको बयान मिलेगा और फिर आपको वह चाहिए जो आपको चाहिए। तो यदि आपका मूल नोड 'MethodDeclerationSyntax' है, तो आप जो चाहते हैं उसे ढूंढने के लिए आपको गहराई से आवश्यकता है। –

+0

@ adeel41 मैं अब अपने फोन से लिख रहा हूं .. मैं जल्द ही अपना जवाब अपडेट कर सकता हूं और आपको यह दिखा सकता हूं कि आपको यह कैसे करना है (यदि आपको आवश्यकता है) –

2

मैं SyntaxTree में सशर्त संकलन नोड नहीं मिलता है और न ही यह {

वास्तव में की } की LeadingTrivia या TrailingTrivia का हिस्सा है, यह return 2; में return कीवर्ड की LeadingTrivia में है।return के लिए नेतृत्व सामान्य ज्ञान है:

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

मुझे जानकारी प्राप्त करने के बारे में कुछ जानकारी देने के लिए धन्यवाद, लेकिन यह सुनिश्चित नहीं है कि मैं ऐसा करूँगा क्योंकि ऐसा लगता है कि मुझे बहुत कुछ करना है। – adeel41

संबंधित मुद्दे