Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

merging C# code with roslyn: comment disappears

Tags:

c#

roslyn

Scenario: I'm trying to use Roslyn to merge a set of C# source fragments into a single code fragment.

Issue: when parsing different classes with a leading comment, the comment above the first class (SomeClass in the example) is not preserved. For the second class (AnotherClass), the comment IS preserved...

The code below demonstrates the issue. Use this in a console program (& install Microsoft.CodeAnalysis.CSharp nuget package)

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
using System.Diagnostics;
using System;

namespace roslyn01
{
    class Program
    {
        static void Main(string[] args)
        {
            var input = new[]
            {
               "// some comment\r\nclass SomeClass {}",
               "// another comment\r\nclass AnotherClass {}",
            };

            // parse all input and collect members
            var members = new List<MemberDeclarationSyntax>();
            foreach (var item in input)
            {
                var syntaxTree = CSharpSyntaxTree.ParseText(item);
                var compilationUnit = (CompilationUnitSyntax)syntaxTree.GetRoot();
                members.AddRange(compilationUnit.Members);
            }

            // assemble all members in a new compilation unit
            var result = SyntaxFactory.CompilationUnit()
                .AddMembers(members.ToArray())
                .NormalizeWhitespace()
                .ToString();

            var expected = @"// some comment
class SomeClass
{
}

// another comment
class AnotherClass
{
}";

            Console.WriteLine(result);
            // the assert fails; the first comment ('// some comment') is missing from the output
            Debug.Assert(expected == result);
        }
    }
}

What am I missing?

like image 791
jeroenh Avatar asked Aug 25 '20 10:08

jeroenh


1 Answers

You are using ToString() instead of ToFullString() when transforming CompilationUnitSyntax to string. ToString() returns a string removing leading and trailing trivia (including comments), but ToFullString() doesn't remove this trivia. You can see it in the code documentation:

//
// Description:
//     Returns the string representation of this node, not including its leading and
//     trailing trivia.
//
// Returns:
//     The string representation of this node, not including its leading and trailing
//     trivia.
//
// Comments:
//     The length of the returned string is always the same as Span.Length
public override string ToString();

//
// Description:
//     Returns full string representation of this node including its leading and trailing
//     trivia.
//
// Returns:
//     The full string representation of this node including its leading and trailing
//     trivia.
//
// Comments:
//     The length of the returned string is always the same as FullSpan.Length
public virtual string ToFullString();
like image 168
JMSilla Avatar answered Oct 31 '22 15:10

JMSilla