2012-06-24 30 views
2

我希望逐步建立一個新的IDocument對象,並使用以下類作爲特定示例。只要生成的對象是一個代表完整類的IDocument,就可以從任何你喜歡的對象開始,使用你喜歡的任何中間對象。什麼是從一開始就建立IDocument的最有效方法

步驟#1:添加一個名爲MyNamespace的新名稱空間。 打印出當前的對象應該是這樣的,在這一點上:

namespace MyNamespace 
{ 
} 

第2步:添加一個新的類此命名空間稱爲MyClass的。 打印出當前的對象應該是這樣的,在這一點上:

namespace MyNamespace 
{ 
    public class MyClass 
    { 
    } 
} 

第3步:添加一個新方法到這個類叫的MyMethod。 打印出當前的對象應該是這樣的,在這一點上:

namespace MyNamespace 
    { 
     public class MyClass 
     { 
      public void MyMethod() 
      { 
      } 
     } 
    } 

我與此遇到的問題是似乎是一個極大的方式理論上你就可以去了解這一點,或至少不正確的結論,你能去做這件事。無限的方法和構造函數在各種不同的對象中,例如WithChanges,UpdateDocument,各種Syntax對象上的方法,ParseCompilationUnit等。

基本上,我想用增量的方式構建它,例如,我可以向控制檯打印,而不是一個大的聲明,它可以在一行中創建整個事件。我已經讀過幾次CTP六月發行版的所有文檔,正如我所提到的,我迷失於各種構造函數和方法的無限組合中。此外,我對一種考慮績效的方式感興趣。

回答

5

要建立一切零碎的建議,我會寫下面的代碼。我還鼓勵你看一下ImplementINotifyPropertyChanged示例,因爲它可以很好地進行語法構建和重寫。請注意,正如你所建議的那樣,有很多方法可以做到這一點。這是因爲API旨在支持諸如編輯器之類的場景,所以您可以通過爲用戶的每個擊鍵應用文本更改來構建此功能。哪個API是正確的取決於你想要達到的目標。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Roslyn.Compilers; 
using Roslyn.Compilers.CSharp; 
using Roslyn.Services; 
using Roslyn.Services.CSharp; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Create the solution with an empty document 
     ProjectId projectId; 
     DocumentId documentId; 
     var solution = Solution.Create(SolutionId.CreateNewId()) 
      .AddProject("MyProject", "MyProject", LanguageNames.CSharp, out projectId) 
      .AddDocument(projectId, @"C:\file.cs", string.Empty, out documentId); 

     var document = solution.GetDocument(documentId); 
     var root = (CompilationUnitSyntax)document.GetSyntaxRoot(); 

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

     Console.WriteLine("-------------------"); 
     Console.WriteLine("With Namespace"); 
     Console.WriteLine(document.GetText().GetText()); 

     // Find our namespace, add a class to it, and update the document 
     var namespaceNode = (NamespaceDeclarationSyntax)root 
      .GetAnnotatedNodesAndTokens(namespaceAnnotation) 
      .Single() 
      .AsNode(); 

     var classAnnotation = new SyntaxAnnotation(); 
     var newNamespaceNode = namespaceNode 
      .WithMembers(
       Syntax.List<MemberDeclarationSyntax>(
        Syntax.ClassDeclaration("MyClass") 
         .WithAdditionalAnnotations(classAnnotation))); 
     root = root.ReplaceNode(namespaceNode, newNamespaceNode).NormalizeWhitespace(); 
     document = document.UpdateSyntaxRoot(root); 

     Console.WriteLine("-------------------"); 
     Console.WriteLine("With Class"); 
     Console.WriteLine(document.GetText().GetText()); 

     // Find the class, add a method to it and update the document 
     var classNode = (ClassDeclarationSyntax)root 
      .GetAnnotatedNodesAndTokens(classAnnotation) 
      .Single() 
      .AsNode(); 
     var newClassNode = classNode 
      .WithMembers(
       Syntax.List<MemberDeclarationSyntax>(
        Syntax.MethodDeclaration(
         Syntax.ParseTypeName("void"), 
         "MyMethod") 
         .WithBody(
          Syntax.Block()))); 
     root = root.ReplaceNode(classNode, newClassNode).NormalizeWhitespace(); 
     document = document.UpdateSyntaxRoot(root); 

     Console.WriteLine("-------------------"); 
     Console.WriteLine("With Method"); 
     Console.WriteLine(document.GetText().GetText()); 
    } 
} 
+0

哇,我以非常低效的方式討論這個問題。我會檢查你提到的樣本。感謝您的幫助,我從您的答案中學到了很多! – Beaker

+0

顯然,有一種更有效的方式來從頭開始構建SyntaxTree,它是這個問題的答案:http://stackoverflow.com/questions/11351977/building-a-syntaxtree-from-the-ground- up – Beaker

+0

當然,但你的問題明確要求介入的步驟。 –

相關問題