如何让Roslyn正确格式化XML文档注释?

3

我正在使用 SyntaxRewriter 来将旧库中的类转换为新库中的类,这基本上涉及查找具有给定属性的类,然后重写遵循特定惯例的属性。 重新编写器的一般框架如下:

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以一致的方式规范化空格?
1个回答

4
我认为这可能是Roslyn的一个bug。然而,一般情况下我建议使用Roslyn.Services.dll中包含的SyntaxNode的Format扩展方法(添加using Roslyn.Services;)。
NormalizeWhitespace是一个非常粗暴的系统,主要设计用于确保代码往返处理。存在于Roslyn.Services层的格式化代码更加灵活,并包含Visual Studio Format Document命令的许多行为。

输出仍然不太对,但比“NormalizeWhitespace”更接近我的期望。 - user7116
你能告诉我有什么不同吗?这可能只是一个错误。 - Kevin Pilch
如果成员之间没有换行符,也没有XML文档注释,则不会在它们之间添加换行符。同样,如果在调用之前两个成员声明没有用换行符分隔开,那么在调用之后它们也不会被分隔开。 - user7116

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接