我正在使用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以一致的方式規範化空白?
輸出仍然不是很正確,但比'NormalizeWhitespace'更接近我的期望。 – user7116
你能告訴我有什麼不同嗎?它可能只是一個錯誤。 –
在成員和XML文檔之間不存在任何新行,如果兩個成員聲明在調用之前沒有用換行符分隔,則不會在之後。 – user7116