替换方法的主体将删除以下换行符

时间:2014-09-09 05:19:57

标签: c# roslyn

我使用以下代码替换Roslyn的方法体;

/* method is instance of MethodDeclarationSyntax */
BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
BlockSyntax body = method.Body;
var modifiedMethod = method.ReplaceNode(body, newBody);

但是当我这样做时,删除方法后换行,如果方法后面有#region#endregion标记,则会发生错误。

例如

    #region
    static void RemoveRegions(string str)
    {
        return;
    }
    #endregion

更换身体后

    #region
    static void RemoveRegions(string str)
    {
        throw new NotImplementedException();
    }        #endregion    // This cause to compiling error

2 个答案:

答案 0 :(得分:12)

原始的BlockSyntax body包含一些" Trailing Trivia"在紧密的大括号之后以空格(换行符)的形式。你构造的BlockSyntax newBody也将包含一个紧密的大括号,但是大括号不知道它后面是否应该有任何空格。

你可以做三件事之一。我认为#1是最好的选择,但我列出其他完整性:

  1. 重用原始节点中的尾部琐事。您可以使用GetTrailingTriviaWithTrailingTrivia来利用原始节点中的尾随琐事:

    var originalTrailingTrivia = body.GetTrailingTrivia();
    newBody = newBody.WithTrailingTrivia(originalTrailingTrivia);
    

    在我看来,这是你最好的选择。它将通过保持任何尾随琐事(无论是一个空白行,五个空白行,零空行和两个空格,一个空格和一个注释等)来保留代码的布局。将更适合您尚未想到的其他场景。

  2. 格式化新节点。让内置的Formatter使用WithAdditionalAnnotations添加Formatter.Annotation并执行{{}来决定如何处理空白3}}在包含newBody

    的树上
    newBody = newBody.WithAdditionalAnnotation(Formatter.Annotation)
    // Code that replaces this node back into the document
    var formattedDocument = Formatter.Format(document, Formatter.Annotation);
    

    请注意,这也将格式化方法的内容。您可以通过将Formatter.Annotation直接添加到关闭大括号本身而不是整个BlockSyntax并遵循相同的步骤来格式化关闭大括号和它周围的标记。这种方法可能会以合理的方式解决问题,但它会删除任何附加在大括号上的评论或故意奇怪的空白。

  3. 手动添加尾随换行符。手动创建换行符并使用WithTrailingTrivia将其添加到newBody

    newBody = newBody.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
    

    这也将删除附加到近花括号的任何注释或故意奇怪的空格。它还会忽略所有上下文,并且不会遵循任何可能更改方法块所需布局的用户指定格式设置。

答案 1 :(得分:1)

Format新节点,或添加SyntaxTrivia