I want to add a comment to the end of a line using Roslyn.
Potentially, I want to add a comment to multiple lines in the same operation, so I would like to work with a DocumentEditor or with a SyntaxRewriter (CSharpSyntaxRewriter or VisualBasicSyntaxRewriter).
Using a DocumentEditor I am able to find the EndOfLineTrivia where I want to insert the comment, but I don't know how to insert the SingleLineCommentTrivia before it.
Is there any way to insert SingleLineCommentTrivia using a DocumentEditor?
Using a SyntaxRewriter, I can override the VisitTrivia method and find the EndOfLineTrivia where I want to insert the comment. I can replace the EndOfLineTrivia with SingleLineCommentTrivia, but then the line break is lost.
Is there any way that I can replace EndOfLineTrivia with a sequence of SingleLineCommentTrivia and EndOfLineTrivia using a SyntaxRewriter?
If neither of these methods is possible, what would be a better way to insert an end-of-line comment?
I think that I have found answers for both cases:
Using a DocumentEditor you can replace a SyntaxNode, but not a SyntaxTrivia.
However all trivia is associated with a SyntaxNode. What you have to do is to locate that SyntaxNode, create a copy of it with modified trivia and then replace the SytnaxNode.
Using SyntaxNode.WithTrailingTrivia(), you can replace the existing trailing trivia with one or more SyntaxTrivia objects.
Without going into every detail, the code is roughly:
SyntaxNode OldNode ;
DocumentEditor RoslynEditor ;
// Initialize OldNode and RoslynEditor ...
var st = SyntaxFactory.Comment ( " // my comment" ) ;
var NewNode = p.WithTrailingTrivia ( st, SyntaxFactory.CarriageReturnLineFeed ) ;
RoslynEditor.ReplaceNode ( p, NewNode ) ;
// and later ...
Dim newRoot = RoslynEditor.GetChangedRoot() ;
Note: This assumes that the end-of-line where the comment should be inserted, is the in the trailing trivia of the SyntaxNode, where it will be replaced. If not, then a new line break will be inserted.
Using a SyntaxRewriter, the trick is to use SyntaxFactory.EndOfLine, to generate a SyntaxToken containing both the end-of-line comment and the actual end of line.
Without showing the details of how to select which line to modify, this is the approximate logic:
class MLHideRewriterCS : CSharpSyntaxRewriter
{
...
public override SyntaxTrivia VisitTrivia ( SyntaxTrivia trivia )
{
// Some logic to detect the correct line ...
if ( this is the line that we want to modify )
{
var expression = SyntaxFactory.EndOfLine ( " // my comment" ) ;
return expression ;
}
return base.VisitTrivia ( trivia ) ;
}
}