title: C# Roslyn change type of comment
body: <p>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:</p>
  
  <pre><code>int newVariable;
  double test;
  </code></pre>
  
  <p>will be changed into:</p>
  
  <pre><code>int iNewVariable;
  double dblTest;
  </code></pre>
  
  <p>Now I have to change this type of comment: (SingleLineComment)</p>
  
  <pre><code>//this is a single line Comment
  </code></pre>
  
  <p>Into a MultiLineComment</p>
  
  <pre><code>/*Here it's a MultiLine one*/
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>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&lt;SyntaxKind&gt;
      {
          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&lt;DiagnosticDescriptor&gt; SupportedDiagnostics
          {
              get { return ImmutableArray.Create(Rule); }
          }
          public ImmutableArray&lt;SyntaxKind&gt; 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&lt;Diagnostic&gt; addDiagnostic, CancellationToken cancellationToken) //Analyse des Nodes
          {
  
              var ifStatement = node as IfStatementSyntax; //Récupération des IfStatement parmis tous les nodes
              if (ifStatement != null &amp;&amp;
                  ifStatement.Statement != null &amp;&amp;
                  !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 &amp;&amp;
                  elseClause.Statement != null &amp;&amp;
                  !elseClause.Statement.IsKind(SyntaxKind.Block) &amp;&amp; //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&lt;DiagnosticDescriptor&gt; SupportedDiagnostics
          {
              get { return ImmutableArray.Create(RuleComment); }
          }
  
          public void AnalyzeSyntaxTree(SyntaxTree tree, Action&lt;Diagnostic&gt; addDiagnostic, CancellationToken cancellationToken)
          {
              var root = tree.GetRoot();
              var trivia = root.DescendantTrivia();
              var a = trivia.Where(x =&gt; x.IsKind(SyntaxKind.SingleLineCommentTrivia)).ToList();
  
              foreach (var b in a)
              {
                  addDiagnostic(Diagnostic.Create(RuleComment, b.GetLocation(), "Commentaire sur une ligne"));
              }
          }
      }
  
  }
  </code></pre>
  
  <p>Here is the CodeFix:</p>
  
  <pre><code>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&lt;string&gt; GetFixableDiagnosticIds()
          {
              return new[] { DiagnosticAnalyzer.DiagnosticId };
          }
  
          public async Task&lt;IEnumerable&lt;CodeAction&gt;&gt; GetFixesAsync(Document document, TextSpan span, IEnumerable&lt;Diagnostic&gt; 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;
          }    
      }
  
  }
  </code></pre>
  
  <p>The user has to click on the advertisement that my program gives and the comment will be changed.</p>
  
  <p>But my program never enters where I have to call the method.</p>
  
  <p>I'm doing my first step with Roslyn, so I don't already know a lot of things, but I'm learning about it..</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>All the code added</p>