2013-04-02 59 views
3

我正在使用SyntaxRewriter將舊庫中的類轉換爲新庫,這基本上需要找到給定屬性的類,然後重寫遵循特定約定的屬性。重寫器的一般骨架如下:如何讓Roslyn格式化XML文檔註釋?

class PropertyConverter : SyntaxRewriter 
{ 
    public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax node) 
    { 
     if (!MeetsUpdateCriteria(node)) return base.VisitPropertyDeclaration(node); 

     // these implementations simply return a string 
     var name = FigureOutName(node.Identifier); 
     var propertyType = FigureOutType(node.Type); 

     var getter = Syntax.ParseExpression("this.GetValue<" + propertyType + ">(" + name + ")"); 
     var setter = Syntax.ParseExpression("this.SetValue(" + name + ", value)"); 

     return node.WithType(propertyType) 
        .WithAccessorList(
      Syntax.AccessorList(Syntax.List(
       Syntax.AccessorDeclaration(
        SyntaxKind.GetAccessorDeclaration, 
        Syntax.Block(Syntax.ReturnStatement(getter))), 
       Syntax.AccessorDeclaration(
        SyntaxKind.SetAccessorDeclaration, 
        Syntax.Block(Syntax.ExpressionStatement(setter))))))); 
    } 
} 

此轉換器的結果是具有更新屬性的類,並且在下面的代碼輸出:

// IDocument csfile <- from a project in a Workspace 
var tree = csfile.GetSyntaxTree(); 
var root = new PropertyConverter().Visit((SyntaxNode)tree.GetRoot()) 
            .NormalizeWhitespace(); // problem! 

File.WriteAllText(Path.GetFileName(csfile.FilePath), root.ToFullString());  

此時的代碼在語法上都是正確的,輸出的語法樹是正確的。我唯一的抱怨是圍繞XML文檔註釋的空白不是任何正確的:

/// <summary> 
     /// Gets or sets the thickness (TH). 
     /// </summary> 
public float Thickness 
{ 
    get 
    { 
     return this.GetValue<float>(TH); 
    } 

    set 
    { 
     this.SetValue(TH, value); 
    } 
} 

注意所有的外部縮進。此外,間距以其他方式破壞爲好,特別是與方法的文檔:

/// <summary> 
     /// Initializes a new instance of the <see cref = "X"/> class. 
     /// </summary> 
     /// <param name = "innerRadius">Inner radius of the X.</param> 
     /// <param name = "thickness">Thickness of the X.</param> 

我驗證過輸入樹沒有從這些壓痕問題的困擾,我也已經驗證了樹的不在致電NormalizeWhitespace之前遇到這些縮進問題。我也試過elasticTrivia: true,沒有任何運氣。

那麼如何讓Roslyn以一致的方式規範化空白?

回答

3

我認爲這可能是Roslyn中的一個錯誤。但是,通常我會建議在Roslyn.Services.dll中包含的SyntaxNode上使用Format擴展方法(添加using Roslyn.Services;)。

NormalizeWhitespace是一個非常暴力的系統,其設計主要是爲了確保代碼將往返。存在於Roslyn.Services圖層中的格式代碼稍微靈活一些,並且包含了Visual Studio Format Document命令的許多行爲。

+0

輸出仍然不是很正確,但比'NormalizeWhitespace'更接近我的期望。 – user7116

+0

你能告訴我有什麼不同嗎?它可能只是一個錯誤。 –

+0

在成員和XML文檔之間不存在任何新行,如果兩個成員聲明在調用之前沒有用換行符分隔,則不會在之後。 – user7116