Roslyn

2012-07-05 16 views
11

का उपयोग कर कक्षा में स्वत: कार्यान्वित संपत्ति जोड़ना मैं ग्राउंड अप से मौजूदा लेकिन सरल एप्लिकेशन बनाकर रोज़लिन सीखने की कोशिश कर रहा हूं, जो इसे सीखने का एक उत्पादक तरीका प्रतीत होता है। किसी भी तरह, मेरे पास निम्न कोड है:Roslyn

var root = (CompilationUnitSyntax)document.GetSyntaxRoot(); 

    // Add the namespace 
    var namespaceAnnotation = new SyntaxAnnotation(); 
    root = root.WithMembers(
     Syntax.NamespaceDeclaration(
      Syntax.ParseName("ACO")) 
       .NormalizeWhitespace() 
       .WithAdditionalAnnotations(namespaceAnnotation)); 
    document = document.UpdateSyntaxRoot(root); 

    // Add a class to the newly created namespace, and update the document 
    var namespaceNode = (NamespaceDeclarationSyntax)root 
     .GetAnnotatedNodesAndTokens(namespaceAnnotation) 
     .Single() 
     .AsNode(); 

    var classAnnotation = new SyntaxAnnotation(); 
    var baseTypeName = Syntax.ParseTypeName("System.Windows.Forms.Form"); 
    SyntaxTokenList syntaxTokenList = new SyntaxTokenList() 
     { 
      Syntax.Token(SyntaxKind.PublicKeyword) 
     }; 

    var newNamespaceNode = namespaceNode 
     .WithMembers(
      Syntax.List<MemberDeclarationSyntax>(
       Syntax.ClassDeclaration("MainForm") 
        .WithAdditionalAnnotations(classAnnotation) 
        .AddBaseListTypes(baseTypeName) 
        .WithModifiers(Syntax.Token(SyntaxKind.PublicKeyword)))); 

    root = root.ReplaceNode(namespaceNode, newNamespaceNode).NormalizeWhitespace(); 
    document = document.UpdateSyntaxRoot(root); 


    var attributes = Syntax.List(Syntax.AttributeDeclaration(Syntax.SeparatedList(Syntax.Attribute(Syntax.ParseName("STAThread"))))); 


    // Find the class just created, add a method to it and update the document 
    var classNode = (ClassDeclarationSyntax)root 
     .GetAnnotatedNodesAndTokens(classAnnotation) 
     .Single() 
     .AsNode(); 

     var syntaxList = Syntax.List<MemberDeclarationSyntax>(
       Syntax.MethodDeclaration(
        Syntax.ParseTypeName("void"), "Main") 
        .WithModifiers(Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword))) 
        .WithAttributes(attributes) 
        .WithBody(
         Syntax.Block())); 
     syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker")); 
     var newClassNode = classNode 
      .WithMembers(syntaxList); 

    root = root.ReplaceNode(classNode, newClassNode).NormalizeWhitespace(); 
    document = document.UpdateSyntaxRoot(root); 

आईडी दस्तावेज़ में निम्न कोड कौन सा आउटपुट करता है।

namespace ACO 
{ 
    public class MainForm : System.Windows.Forms.Form 
    { 
     [STAThread] 
     public void Main() 
     { 
     } 
    } 
} 

हालांकि यह इस तरह दिखना चाहिए

namespace ACO 
{ 
    public class MainForm : System.Windows.Forms.Form 
    { 
    public System.Windows.Forms.Timer Ticker {get; set;} 

     [STAThread] 
     public void Main() 
     { 
     } 
    } 
} 

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


ऐसा लगता है कि मैं इस लाइन को बदलने के लिए की जरूरत: इस लाइन के लिए

syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker")); 

:

namespace ACO 
{ 
    public class MainForm : System.Windows.Forms.Form 
    { 
     [STAThread] 
     public void Main() 
     { 
     } 

     System.Windows.Forms.Timer Ticker 
     { 
     } 
    } 
} 
:

syntaxList = syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker")); 

हालांकि, अब मैं इस आउटपुट प्राप्त

अब मुझे "मिलना; सेट;" नहीं मिल रहा है संपत्ति के भीतर पाठ। क्या किसी को पता है कि मैं क्या खो रहा हूँ?

उत्तर

7

मुझे लगता है कि संपत्ति क्यों नहीं जोड़ा गया था SyntaxList एस, Roslyn में सब कुछ की तरह, अपरिवर्तनीय हैं। Add() अद्यतन SyntaxList वापस नहीं करता है? (मैं अभी यह सत्यापित नहीं कर सकता, मैंने अभी तक नए सीटीपी पर स्विच नहीं किया है।)

और रोज़लिन में इस तरह का कोड बहुत वर्बोज़ हो सकता है, लेकिन आप इसे आवश्यक से अधिक जटिल बना रहे हैं। यदि आप नीचे से सिंटैक्स पेड़ बनाते हैं, तो आपको प्रत्येक बदलाव के बाद root अपडेट करने की आवश्यकता नहीं है: पहले कक्षा के सदस्यों, फिर कक्षा, फिर नामस्थान बनाएं। यदि आप ऐसा करते हैं, तो आपको सभी टिप्पणियों से निपटने की ज़रूरत नहीं होगी।

+0

अचल स्थिति का आपका रिमाइंडर मुझे नेतृत्व का एहसास करने मैं गलत जो मैं नीचे पोस्ट क्या कर रहा था। मैं नीचे से अपने विशेष सिंटेक्स ट्री को वास्तव में बनाने के तरीके के बारे में एक अलग सवाल पूछूंगा। – Beaker

+0

मेरे नए प्रश्न का लिंक यहां बताया गया है कि मैं अपने सिंटेक्स ट्री को जमीन से ऊपर कैसे बना सकता हूं जैसा आपने सुझाव दिया था। http://stackoverflow.com/questions/11351977/roslyn-ctp-building-a-syntaxtree-from-the-ground-up – Beaker

+1

आपके दूसरे प्रश्न में मैंने क्वाटर नामक टूल पर एक लिंक जोड़ा है जो मदद कर सकता है किसी भी प्रोग्राम के लिए रोज़लिन सिंटैक्स एपीआई कॉल स्वचालित रूप से उत्पन्न करने में: http://blogs.msdn.com/b/kirillosenkov/archive/2012/07/22/roslyn-code-quoter-tool-generating-syntax-tree-api- कॉल के लिए किसी भी-सी program.aspx –

5

नई धाराप्रवाह एपीआई का उपयोग करना (.With ...() विधि) अब आप उपयोग कर सकते हैं:

Syntax.PropertyDeclaration(Syntax.ParseTypeName("int"), "MyProperty") 
     .WithAccessorList(
      Syntax.AccessorList(
       Syntax.List(
        Syntax.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) 
         .WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)), 
        Syntax.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) 
         .WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)))));