C#罗斯林变化类型的注释 [英] C# Roslyn change type of comment

查看:277
本文介绍了C#罗斯林变化类型的注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让Visual Studio的一个扩展,在代码改变了一些语法。
事实上,我已经做了第一步,这是改变一个变量的名字,如果这个名字是不是好与我们在公司使用的规则。例如:

I'm trying to make an extension for Visual Studio that changes some syntax in the code. Actually, I've done the first step which was to change the name of a variable if this name was not okey with the rules we use in the firm. For example:

int newVariable;
double test;



将变为:

will be changed into:

int iNewVariable;
double dblTest;

现在我要改变这种类型的注释:(SingleLineComment)

Now I have to change this type of comment: (SingleLineComment)

//this is a single line Comment

进入一个MultiLineComment

Into a MultiLineComment

/*Here it's a MultiLine one*/

我用的是罗斯林语法Visualiser的找到类型和种类做出正确的代码,但没有任何工程。
这就是我的诊断完成的:

I use the Roslyn Syntax Visualiser to find the type and kind to make a correct code, but nothing works. Here it's what I've done for the Diagnostic:

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace CodeFix
{
    [DiagnosticAnalyzer]
    [ExportDiagnosticAnalyzer(DiagnosticId, LanguageNames.CSharp)]
    public class DiagnosticAnalyzer : ISyntaxNodeAnalyzer<SyntaxKind>
    {
        internal const string DiagnosticId = "CodeFix";
        internal const string Description = "Mauvais formattage";
        internal const string MessageFormat = "'{0}'";
        internal const string Category = "Correction";

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

        public ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
        {
            get { return ImmutableArray.Create(Rule); }
        }
        public ImmutableArray<SyntaxKind> SyntaxKindsOfInterest //Ce qui nous intéresse
        {
            get
            {
                return ImmutableArray.Create(SyntaxKind.IfStatement, SyntaxKind.ElseClause, SyntaxKind.LocalDeclarationStatement, SyntaxKind.ConstKeyword, SyntaxKind.SingleLineCommentTrivia, SyntaxKind.SimpleAssignmentExpression);
            }
        }
        public void AnalyzeNode(SyntaxNode node, SemanticModel model, Action<Diagnostic> addDiagnostic, CancellationToken cancellationToken) //Analyse des Nodes
        {

            var ifStatement = node as IfStatementSyntax; //Récupération des IfStatement parmis tous les nodes
            if (ifStatement != null &&
                ifStatement.Statement != null &&
                !ifStatement.Statement.IsKind(SyntaxKind.Block))
            {
                addDiagnostic(Diagnostic.Create(Rule, ifStatement.IfKeyword.GetLocation(), "Le if require des crochets"));
            }

            var elseClause = node as ElseClauseSyntax; //Récupération des Else parmis tous les nodes
            if (elseClause != null &&
                elseClause.Statement != null &&
                !elseClause.Statement.IsKind(SyntaxKind.Block) && //Pas que ce soit déjà un block avec {}
                !elseClause.Statement.IsKind(SyntaxKind.IfStatement)) //A cause des else if
            {
                addDiagnostic(Diagnostic.Create(Rule, elseClause.ElseKeyword.GetLocation(), "le else require des crochets"));
            }

        }
    }
    internal class IDiagnosticAnalyzer : ISyntaxTreeAnalyzer
    {
        internal const string DiagnosticIdComment = "CommentChanger";
        internal const string DescriptionComment = "Les commentaires doivent être en format /* */";
        internal const string MessageFormatComment = "'{0}' doit être en multiline";
        internal const string CategoryComment = "Renommage";

        internal static DiagnosticDescriptor RuleComment = new DiagnosticDescriptor(DiagnosticIdComment, DescriptionComment, MessageFormatComment, CategoryComment, DiagnosticSeverity.Warning);

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

        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(RuleComment, b.GetLocation(), "Commentaire sur une ligne"));
            }
        }
    }

}

下面是CodeFix:

Here is the CodeFix:

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Rename;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Formatting;
using System;

namespace CodeFix
{
    [ExportCodeFixProvider(DiagnosticAnalyzer.DiagnosticId, LanguageNames.CSharp)]
    internal class CodeFixProvider : ICodeFixProvider
    {
        public IEnumerable<string> GetFixableDiagnosticIds()
        {
            return new[] { DiagnosticAnalyzer.DiagnosticId };
        }

        public async Task<IEnumerable<CodeAction>> GetFixesAsync(Document document, TextSpan span, IEnumerable<Diagnostic> diagnostics, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken); //Document à utiliser (root)
            var token = root.FindToken(span.Start); //


            if (token.IsKind(SyntaxKind.IfKeyword))
            {
                var ifStatement = (IfStatementSyntax)token.Parent;
                var newIfStatement = ifStatement
                    .WithStatement(SyntaxFactory.Block(ifStatement.Statement))
                    .WithAdditionalAnnotations(Formatter.Annotation); //Pour que ce soit indenté juste

                var newRoot = root.ReplaceNode(ifStatement, newIfStatement); 

                return new[] { CodeAction.Create("Ajouter des crochets", document.WithSyntaxRoot(newRoot)) };
            }

            if (token.IsKind(SyntaxKind.ElseKeyword))
            {
                var elseClause = (ElseClauseSyntax)token.Parent;
                var newElseClause = elseClause
                    .WithStatement(SyntaxFactory.Block(elseClause.Statement))
                    .WithAdditionalAnnotations(Formatter.Annotation);

                var newRoot = root.ReplaceNode(elseClause, newElseClause);

                return new[] { CodeAction.Create("Ajouter des crochets", document.WithSyntaxRoot(newRoot)) };
            }

            if (token.IsKind(SyntaxKind.SingleLineCommentTrivia))
            {

                var root1 = await document.GetSyntaxRootAsync(cancellationToken);
                var token1 = root1.FindToken(span.Start);
                var allTrivia = token1.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;
        }    
    }

}



用户有点击我的程序给和注释将被改变广告。

The user has to click on the advertisement that my program gives and the comment will be changed.

但我的计划从来没有进入,我要调用的方法。

But my program never enters where I have to call the method.

我在做我的罗斯林第一步,所以我还不知道很多东西,但我了解它。

I'm doing my first step with Roslyn, so I don't already know a lot of things, but I'm learning about it..

编辑:

添加所有的代码

推荐答案

我已经把使用CodeFix一个例子与诊断,取代单行具有多行的人评论。下面是一些代码。它的很多是基于构建达斯汀·坎贝尔的罗斯林演示可在 HTTP可以看出: //channel9.msdn.com/Events/Build/2014/2-577

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从ISyntaxTreeAnalyzer实现找到单行注释:

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"));
        }
    }
}

从ICodeFixProvider

GetFixesAsync实现:

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;
    }

这篇关于C#罗斯林变化类型的注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆