C# Roslyn change type of comment

爷,独闯天下 提交于 2019-12-04 15:48:28

I've put together an example using a CodeFix with a Diagnostic that replaces single line comments with multiline ones. Here's some of the code. Alot of it is based on Dustin Campbell's Roslyn demo from Build which can be seen at http://channel9.msdn.com/Events/Build/2014/2-577

AnalyzeSyntaxTree implementation from ISyntaxTreeAnalyzer to find single line comments:

[DiagnosticAnalyzer]
[ExportDiagnosticAnalyzer(DiagnosticId, LanguageNames.CSharp)]
internal class DiagnosticAnalyzer : ISyntaxTreeAnalyzer
{
    internal const string DiagnosticId = "CommentChanger";
    internal const string Description = "Single comments should be multiline comments";
    internal const string MessageFormat = "'{0}' should be multiline";
    internal const string Category = "Naming";

    internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Description, MessageFormat, Category, DiagnosticSeverity.Warning);

    public ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
    {
        get { return ImmutableArray.Create(Rule); }
    }

    public void AnalyzeSyntaxTree(SyntaxTree tree, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken)
    {
        var root = tree.GetRoot();
        var trivia = root.DescendantTrivia();
        var a = trivia.Where(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia)).ToList();

        foreach(var b in a)
        {
            addDiagnostic(Diagnostic.Create(Rule, b.GetLocation(), "Single comment"));
        }
    }
}

GetFixesAsync implementation from ICodeFixProvider:

public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
    {
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var token = root.FindToken(span.Start);
        var allTrivia = token.GetAllTrivia();
        foreach(var singleTrivia in allTrivia)
        {
            if (singleTrivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
            {
                var commentContent = singleTrivia.ToString().Replace("//", string.Empty);
                var newComment = SyntaxFactory.Comment(string.Format("/*{0}*/", commentContent));
                var newRoot = root.ReplaceTrivia(singleTrivia, newComment);
                return new[] { CodeAction.Create("Convert to multiline", document.WithSyntaxRoot(newRoot)) };
            }
        }           
        return null;
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!