I'm using the following code to replace the body of methods by 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);
But when I do this, line breaks after the methods are removed and if there is a #region
or #endregion
tag after the method an error will occur.
For example
#region
static void RemoveRegions(string str)
{
return;
}
#endregion
And after replacing the body
#region
static void RemoveRegions(string str)
{
throw new NotImplementedException();
} #endregion // This cause to compiling error
Remove All Line Breaks from a String We can remove all line breaks by using a regex to match all the line breaks by writing: str = str. replace(/(\r\n|\n|\r)/gm, ""); \r\n is the CRLF line break used by Windows.
The original BlockSyntax body
contained some "Trailing Trivia" in the form of whitespace (a newline) after the close curly brace. Your constructed BlockSyntax newBody
will contain a close curly brace as well, but that curly brace doesn't know whether or not it should have any whitespace after it.
You could do one of three things. I think #1 is the best option but I'm listing the others for completeness:
Reuse the trailing trivia from the original node. You can make use of the trailing trivia from the original node by using GetTrailingTrivia and WithTrailingTrivia:
var originalTrailingTrivia = body.GetTrailingTrivia();
newBody = newBody.WithTrailingTrivia(originalTrailingTrivia);
In my opinion, this is your best bet. It will preserve the layout of the code by keeping around any trailing trivia (whether it be one blank line, five blank lines, zero blank lines and two spaces, one space and a comment, etc.) and will be more generally suited to other scenarios you haven't dreamed up yet.
Format the new node. Let the built-in Formatter decide how to handle the whitespace by using WithAdditionalAnnotations to add the Formatter.Annotation and perform a Formatter.FormatAsync on the tree containing the newBody
:
newBody = newBody.WithAdditionalAnnotation(Formatter.Annotation)
// Code that replaces this node back into the document
var formattedDocument = Formatter.Format(document, Formatter.Annotation);
Note that this will also format the contents of the method. You could format only the close curly brace and tokens around it by adding the Formatter.Annotation directly to the close curly brace itself instead of the entire BlockSyntax and following the same steps. This approach may lay things out in a reasonable way, but it will remove any comments or intentionally strange whitespace attached to the close curly brace.
Add a trailing newline manually. Create a newline manually and add it to newBody
with WithTrailingTrivia:
newBody = newBody.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);
This will also remove any comments or intentionally strange whitespace attached to the close curly brace. It also ignores all context and will not honor any user-specified formatting settings that might change the desired layout of method blocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With