How to remove all comments in a .cs textfile with Roslyn?
-
vendredi 23 décembre 2011 07:18
How to remove all comments and all trailing whitespaces in a .cs textfile with Roslyn?
Can anyone provide a sample?
Thanks.
- Modifié Enih vendredi 23 décembre 2011 08:27
Toutes les réponses
-
vendredi 23 décembre 2011 22:01
This is a code action I had written that should remove single and multiline comments in a selected piece of text. To remove trailing whitespace it is probably easier to directly manipulate the document as a string or array of lines than to remove whitespace trivia through Roslyn.[ExportCodeRefactoringProvider("RemoveComments", LanguageNames.CSharp)] class RemoveCommentsCodeRefactoringProvider : ICodeRefactoringProvider { ICodeActionEditFactory editFactory; [ImportingConstructor] public RemoveCommentsCodeRefactoringProvider(ICodeActionEditFactory editFactory) { this.editFactory = editFactory; } public CodeRefactoring GetRefactoring(IDocument document, TextSpan textSpan, CancellationToken cancellationToken) { return new CodeRefactoring(new ICodeAction[] { new RemoveCommentsCodeAction(editFactory, document) }); } } class RemoveCommentsCodeAction : ICodeAction { ICodeActionEditFactory editFactory; IDocument document; public RemoveCommentsCodeAction(ICodeActionEditFactory editFactory, IDocument document) { this.editFactory = editFactory; this.document = document; } public string Description { get { return "Remove all comments"; } } public ICodeActionEdit GetEdit(CancellationToken cancellationToken) { var tree = (SyntaxTree)document.GetSyntaxTree(cancellationToken); var commentTrivia = from t in tree.Root.DescendentTrivia() where t.Kind == SyntaxKind.SingleLineCommentTrivia || t.Kind == SyntaxKind.MultiLineCommentTrivia select t; var newRoot = tree.Root.ReplaceTrivia(commentTrivia, (t1, t2) => SyntaxTriviaList.Empty); return editFactory.CreateTreeTransformEdit(document.Project.Solution, tree, newRoot); } public ImageSource Icon { get { return null; } } }
- Proposé comme réponse Shyam NamboodiripadMicrosoft Employee, Owner mercredi 4 janvier 2012 02:29
- Marqué comme réponse billchi_msOwner mardi 17 janvier 2012 00:31
-
mardi 27 décembre 2011 22:19Propriétaire
Hi - The ICodeAction code posted by Chrysler above should work if you are trying this from within a Roslyn VS Extension. You can also write code that works outside VS (in a Roslyn Console Application for example) as shown below. The below examples use SyntaxRewriters and the .Format() extension method to remove comments and redundant trailing whitespaces.
using System;
using System.Linq;
using Roslyn.Compilers.CSharp;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
var tree = SyntaxTree.ParseCompilationUnit(
@"class Program
{
// SingleLineComment
public static void Main()
{
/*
MultiLineComment
MultiLineComment
MultiLineComment
*/
}
}");
// Solution 1 - Use a SyntaxRewriter to remove
// redundant trailing whitespace and comments
SyntaxRewriter rewriter = new Rewriter1();
var newRoot = rewriter.Visit(tree.Root);
Console.WriteLine(newRoot.GetFullText());
// Solution 2 - Use a SyntaxRewriter to remove comments
// and call .Format() extension method which will pretty-format
// the source code and remove any redundant trailing whitesepace
rewriter = new Rewriter2();
newRoot = rewriter.Visit(tree.Root).Format();
Console.WriteLine(newRoot.GetFullText());
// Solution 3 - Use ReplaceTrivia() to remove comments as Chrysler pointed out above
// and call .Format() extension method which will pretty-format
// the source code and remove any redundant trailing whitesepace
var commentTrivia = from t in tree.Root.DescendentTrivia()
where t.Kind == SyntaxKind.SingleLineCommentTrivia ||
t.Kind == SyntaxKind.MultiLineCommentTrivia
select t;
newRoot = tree.Root.ReplaceTrivia(commentTrivia, (t1, t2) => SyntaxTriviaList.Empty).Format();
Console.WriteLine(newRoot.GetFullText());
}
class Rewriter1 : SyntaxRewriter
{
protected override SyntaxToken VisitToken(SyntaxToken token)
{
return token
.WithLeadingTrivia(RemoveCommentsAndRedundantTrailingWhitespace(token.LeadingTrivia))
.WithTrailingTrivia(RemoveCommentsAndRedundantTrailingWhitespace(token.TrailingTrivia));
}
private SyntaxTriviaList RemoveCommentsAndRedundantTrailingWhitespace(SyntaxTriviaList oldTriviaList)
{
var newTriviaList = new List<SyntaxTrivia>();
for (var i = 0; i < oldTriviaList.Count; ++i)
{
var isComment =
oldTriviaList[i].Kind == SyntaxKind.SingleLineCommentTrivia ||
oldTriviaList[i].Kind == SyntaxKind.MultiLineCommentTrivia;
var isRedundantWhitespace =
i + 1 < oldTriviaList.Count &&
oldTriviaList[i].Kind == SyntaxKind.WhitespaceTrivia &&
oldTriviaList[i + 1].Kind == SyntaxKind.EndOfLineTrivia;
if (!isComment && !isRedundantWhitespace)
{
newTriviaList.Add(oldTriviaList[i]);
}
}
return Syntax.TriviaList(newTriviaList);
}
}
class Rewriter2 : SyntaxRewriter
{
protected override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
{
var newTrivia = trivia;
if (trivia.Kind == SyntaxKind.SingleLineCommentTrivia ||
trivia.Kind == SyntaxKind.MultiLineCommentTrivia)
{
newTrivia = default(SyntaxTrivia);
}
return newTrivia;
}
}
}
Shyam Namboodiripad | Software Development Engineer in Test | Roslyn Compilers Team- Modifié Shyam NamboodiripadMicrosoft Employee, Owner mardi 27 décembre 2011 22:20
- Proposé comme réponse Shyam NamboodiripadMicrosoft Employee, Owner mercredi 4 janvier 2012 02:29
- Marqué comme réponse billchi_msOwner mardi 17 janvier 2012 00:31

