File: Formatting\FormattingTriviaTests.cs
Web Access
Project: src\src\Workspaces\CSharpTest\Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Workspaces.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Formatting;
 
[Trait(Traits.Feature, Traits.Features.Formatting)]
public sealed class FormattingEngineTriviaTests : CSharpFormattingTestBase
{
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/31130")]
    public Task PreprocessorNullable()
        => AssertFormatAsync("""
            #nullable
            class C
            {
            #nullable enable
                void Method()
                {
            #nullable disable
                }
            }
            """, """
                #nullable
            class C
            {
                #nullable     enable
                void Method()
                {
                    #nullable    disable
                }
            }
            """);
 
    [Fact]
    public Task PreprocessorInEmptyFile()
        => AssertFormatAsync("""
            #line 1000
            #error
            """, """
                #line 1000
            #error
            """);
 
    [Fact]
    public Task Comment1()
        => AssertFormatAsync("""
            // single line comment
            class C { }
            """, """
             // single line comment
            class C {           }
            """);
 
    [Fact]
    public Task Comment2()
        => AssertFormatAsync("""
            class C
            {
                // single line comment
                int i;
            }
            """, """
            class C 
            {
                            // single line comment
                int i;
            }
            """);
 
    [Fact]
    public Task Comment3()
        => AssertFormatAsync("""
            class C
            {
                // single line comment
            }
            """, """
            class C 
            {
                            // single line comment
            }
            """);
 
    [Fact]
    public Task Comment4()
        => AssertFormatAsync("""
            class C
            {
                // single line comment
                //  single line comment 2
                void Method() { }
            }
            """, """
            class C 
            {
                            // single line comment
            //  single line comment 2
                void Method() { }
            }
            """);
 
    [Fact]
    public Task Comment5()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    // single line comment
                    //  single line comment 2
                }
            }
            """, """
            class C 
            {
                void Method() { 
                // single line comment
                //  single line comment 2
            }
            }
            """);
 
    [Fact]
    public Task Comment6()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    // single line comment
                    //  single line comment 2
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                // single line comment
                //  single line comment 2
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment7()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    // single line comment
 
                    int i = 10;
 
                    //  single line comment 2
                }
            }
            """, """
            class C 
            {
                void Method() { 
                // single line comment
 
                    int i = 10;
 
                //  single line comment 2
            }
            }
            """);
 
    [Fact]
    public Task Comment8()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* multiline comment */
 
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                    /* multiline comment */
 
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment9()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* multiline comment */
 
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                    /* multiline comment */
 
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment10()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* multiline comment */
 
                    int i = 10;
                    /* multiline comment */
                }
            }
            """, """
            class C 
            {
                void Method() { 
                    /* multiline comment */
 
                    int i = 10;
            /* multiline comment */
            }
            }
            """);
 
    [Fact]
    public Task Comment11()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* 
                     * multiline comment 
                     */
 
                    int i = 10;
 
                    /* 
                     * multiline comment 
                     */
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                /* 
                                 * multiline comment 
                                 */
 
                    int i = 10;
 
            /* 
             * multiline comment 
             */
            }
            }
            """);
 
    [Fact]
    public Task Comment12()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* 
            * multiline comment 
            */
 
                    int i = 10;
 
                    /* 
            * multiline comment 
            */
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                                                    /* 
                                 * multiline comment 
                                 */
 
                    int i = 10;
 
                                        /* 
                         * multiline comment 
                         */
            }
            }
            """);
 
    [Fact]
    public Task Comment13()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                { // test
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { // test
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment14()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                { // test
                  // test 2
                  // test 3
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { // test
                                // test 2
                                // test 3
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment15()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                { /* test */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { /* test */
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment16()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                { /* test 
                                 *      
                                 */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { /* test 
                                 *      
                                 */         
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment17()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* test 
                     *      
                     */         // test
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                /* test 
                                 *      
                                 */         // test
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment18()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* test 
                     *      
                     */         // test     
                                // test 2       
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                /* test 
                                 *      
                                 */         // test     
                                            // test 2       
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment19()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* test 
                     *      
                     */         /* test 2
                                 *
                                 */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                /* test 
                                 *      
                                 */         /* test 2
                                             *
                                             */
                    int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment20()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i = 10;
                    /* test 
                     *      
                     */         /* test 2
                                 *
                                 */
                }
            }
            """, """
            class C 
            {
                void Method() { 
                    int i = 10;
                                /* test 
                                 *      
                                 */         /* test 2
                                             *
                                             */
            }
            }
            """);
 
    // for now, formatting engine doesn't re-indent token if the indentation line contains noisy
    // chars
    [Fact]
    public Task Comment21()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /* */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                        /* */ int i = 10;
            }
            }
            """);
 
    // for now, formatting engine doesn't re-indent token if the indentation line contains noisy
    // chars
    [Fact]
    public Task Comment22()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i =
                        /* */ 10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                        int i = 
                                            /* */ 10;
            }
            }
            """);
 
    [Fact]
    public Task Comment23()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int /* */ i = /* */         10;
                }
            }
            """, """
            class C 
            {
                void Method() { 
                                        int /* */ i             = /* */         10;
            }
            }
            """);
 
    [Fact]
    public Task Comment24()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /*
                     */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
                    /*
                     */   int i             =          10;
            }
            }
            """);
 
    [Fact]
    public Task DocComment1()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /**
                     */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
                                            /**
                                             */   
                            int i             =          10;
            }
            }
            """);
 
    [Fact]
    public Task DocComment2()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {     /**
                                     */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     /**
                                     */   
                            int i             =          10;
            }
            }
            """);
 
    [Fact]
    public Task DocComment3()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i = 10;
                    /**
                     */
                }
            }
            """, """
            class C 
            {
                void Method() {     
                            int i             =          10;
                                    /**
                                     */
            }
            }
            """);
 
    [Fact]
    public Task DocComment4()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i = 10; /**                
                                     */
                }
            }
            """, """
            class C 
            {
                void Method() {     
                            int i             =          10; /**                
                                     */
            }
            }
            """);
 
    [Fact]
    public Task DocComment5()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i = 10; /** */
                }
            }
            """, """
            class C 
            {
                void Method() {     
                            int i             =          10; /** */
            }
            }
            """);
 
    [Fact]
    public Task DocComment6()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i /** */            =
                        /** */ 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
                            int i /** */            =     
                                /** */ 10; 
            }
            }
            """);
 
    [Fact]
    public Task DocComment7()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {     ///
                      ///
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     ///
                                    ///
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task DocComment8()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    ///
                    ///
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
                                    ///
                                    ///
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task DocComment9()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int i = 10;
                    ///
                    ///
                }
            }
            """, """
            class C 
            {
                void Method() {     
                            int i = 10; 
            ///
                                    ///
            }
            }
            """);
 
    [Fact]
    public Task DocComment10()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    ///
                    /**
                     */ ///
                        ///
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
            ///
            /**
             */ ///
                ///
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task DocComment11()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    ///
                    /**
                     */ /**
                          *
                          */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
            ///
            /**
             */ /**
                  *
                  */
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task DocComment12()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    ///
                    /**
                     */ /** */
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
            ///
            /**
             */ /** */
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task MixCommentAndDocComment1()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    //
                    /**
                     */ /*          
                         */ //
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
            //
            /**
             */ /*          
                 */ //
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task MixCommentAndDocComment2()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    /*
                     *
                     */ /**          
                         *
                         */ /*
                     *
                     */ ///
                        ///
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
            /*
             *
             */ /**          
                 *
                 */ /*
             *
             */ ///
                ///
                            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task MixCommentAndDocComment3()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    // test
                    // test 2
 
                    /// <text></text>
                    /// test 3
                    ///
 
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                void Method() {     
                        // test
                        // test 2
 
                        /// <text></text>
                        /// test 3
                        ///
 
            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task MixCommentAndDocComment4()
        => AssertFormatAsync("""
            class C
            {
                /// <text></text>
                /// test 3
                ///
                void Method()
                {
                    // test
                    // test 2
 
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                        /// <text></text>
                        /// test 3
                        ///
            void Method() {     
                        // test
                        // test 2
 
            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task Preprocessor1()
        => AssertFormatAsync("""
            class C
            {
            #if true
            #endif
                void Method()
                {
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                                #if true
                                #endif
            void Method() {     
            int i = 10; 
            }
            }
            """);
 
    [Fact]
    public Task Preprocessor2()
        => AssertFormatAsync("""
            class C
            {
            #if true
                void Method()
                {
                    int i = 10;
                }
            }
            #endif
            """, """
            class C 
            {
                                #if true
            void Method() {     
            int i = 10; 
            }
            }
                #endif
            """);
 
    [Fact]
    public Task Preprocessor3()
        => AssertFormatAsync("""
            class C
            {
            #if true
                void Method()
                {
            #elif false
            int i = 10; 
            }
            }
            #endif
                }
            }
            """, """
            class C 
            {
                                #if true
            void Method() {     
                            #elif false
            int i = 10; 
            }
            }
                #endif
            }
            }
            """);
 
    [Fact]
    public Task Preprocessor4()
        => AssertFormatAsync("""
            class C
            {
            #if true
                void Method()
                {
                }
            #elif false
            int i = 10; 
            }
            #endif
            }
            """, """
            class C 
            {
                                #if true
            void Method() {     
            }
                            #elif false
            int i = 10; 
            }
                #endif
            }
            """);
 
    [Fact]
    public Task Preprocessor5()
        => AssertFormatAsync("""
            class C
            {
                #region Test
                int i = 10;
                #endregion
 
                void Method()
                {
                }
            }
            """, """
            class C 
            {
                                #region Test
                    int i = 10;
                                #endregion
 
            void Method() {     
            }
            }
            """);
 
    [Fact]
    public Task Preprocessor6()
        => AssertFormatAsync("""
            class C
            {
                #region Test
                int i = 10;
                #endregion
 
                void Method()
                {
                }
            }
            """, """
            class C 
            {
                                #region Test
                    int i = 10;
                                #endregion
 
            void Method() {     
            }
            }
            """);
 
    [Fact]
    public Task Preprocessor7()
        => AssertFormatAsync("""
            class C
            {
                #region Test
                int i = 10;
 
                void Method()
                {
                }
                #endregion
            }
            """, """
            class C 
            {
                                #region Test
                    int i = 10;
 
            void Method() {     
            }
            #endregion
            }
            """);
 
    [Fact]
    public Task Preprocessor8()
        => AssertFormatAsync("""
            class C
            {
                #region Test
                int i = 10;
 
                void Method()
                {
                    #endregion
                    int i = 10;
                }
            }
            """, """
            class C 
            {
                                #region Test
                    int i = 10;
 
            void Method() {     
            #endregion
            int i = 10;
            }
            }
            """);
 
    [Fact]
    public Task MixAll()
        => AssertFormatAsync("""
            class C
            {
                #region Test
 
            #if true
 
                // test
                ///
                ///
                int i = 10;
 
            #else
            void Method() {     
            }
            #endif
                #endregion
            }
            """, """
            class C 
            {
                                #region Test
 
                        #if true
 
                                    // test
                            ///
                            ///
                    int i = 10;
 
                        #else                    
            void Method() {     
            }
                #endif
            #endregion
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537895")]
    public Task Preprocessor9()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    #region Myregion
                    int a;
                    if (true)
                        a++;
                    #endregion
                }
            }
            """, """
            class C 
            {
            void Method() {     
            #region Myregion
                        int a;
                        if (true)
                            a++;
                        #endregion 
            }
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537895")]
    public Task Preprocessor10()
        => AssertFormatAsync("""
            class C
            {
                void Method()
                {
                    int a;
                    if (true)
                        a++;
                    #region Myregion
                }
            }
            """, """
            class C 
            {
            void Method() {     
                        int a;
                        if (true)
                            a++;
            #region Myregion
            }
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537765")]
    public Task Comment25()
        => AssertFormatAsync("""
            class C
            {
                void Goo()//method
                {
                    int x;//variable
                    double y;
                }
            }
            """, """
            class C 
            {
                        void Goo()//method
            {
                int x;//variable
            double y;
                                }
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537765")]
    public Task Comment26()
        => AssertFormatAsync("""
            public class Class1
            {
                void Goo()
                {
                    /**/
                    int x;
                }
            }
            """, """
            public class Class1
            {
                void Goo()
                {
            /**/int x;
                }
            }
            """);
 
    [Fact]
    public async Task Comment27()
    {
        var content = """
            public class Class1
            {
                void Goo()
                {
                    //      
                    // 
                }
            }
            """;
 
        await AssertFormatAsync(content, content);
    }
 
    [Fact]
    public Task Comment28()
        => AssertFormatAsync("""
            public class Class1
            {
                void Goo()
                {
                    //      
 
                    // 
 
                }
            }
            """, """
            public class Class1
            {
                void Goo()
                {
                    //      
 
                    // 
 
                }
            }
            """);
 
    [Fact]
    public Task Comment29()
        => AssertFormatAsync("""
            public class Class1
            {
                void Goo()
                {
                    int         /**/ i = 10;
                }
            }
            """, """
            public class Class1
            {
                void Goo()
                {
                    int			/**/ i = 10;
                }
            }
            """);
 
    [Fact]
    public Task Comment30()
        => AssertFormatAsync("""
            // Test
            """, """
            // Test
            """);
 
    [Fact]
    public Task Comment31()
        => AssertFormatAsync("""
            /// <summary>
            ///
            /// </summary>
            class Program
            {
                static void Main(string[] args)
                {
                }
            }
            """, """
            /// <summary>
            ///
                    /// </summary>
            class Program
            {
                static void Main(string[] args)
                {
                }
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538703")]
    public Task Comment32()
        => AssertFormatAsync("""
            class Program
            {
                ///<summary>
                ///     TestMethod
                ///</summary>
                void Method() { }
            }
            """, """
            class Program
            {
                ///<summary>
                    ///     TestMethod
            ///</summary>
                void Method() { }
            }
            """);
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542316")]
    public Task CommentInExpression()
        => AssertFormatAsync("""
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            class Program
            {
                static void Main(string[] args)
                {
                    CreateCompilationWithMscorlib(source).VerifyDiagnostics(
                        // (10,30): error CS0455: Type parameter 'X' inherits conflicting constraints 'B' and 'A'
                        Diagnostic(ErrorCode.ERR_BaseConstraintConflict, "X").WithArguments("X", "B", "A").WithLocation(10, 30));
                }
            }
            """, """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            class Program
            {
                static void Main(string[] args)
                {
                    CreateCompilationWithMscorlib(source).VerifyDiagnostics(
                                        // (10,30): error CS0455: Type parameter 'X' inherits conflicting constraints 'B' and 'A'
                        Diagnostic(ErrorCode.ERR_BaseConstraintConflict, "X").WithArguments("X", "B", "A").WithLocation(10, 30));
                }
            }
            """);
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")]
    [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542546")]
    public Task FormatInvalidCode_1()
        => AssertFormatAsync(@"> Roslyn.Utilities.dll!   Basic", @">	Roslyn.Utilities.dll! 	Basic");
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/44423")]
    [WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542546")]
    public Task FormatInvalidCode_2()
        => AssertFormatAsync(@"> Roslyn.Utilities.dll! Line 43 + 0x5 bytes	Basic", @">	Roslyn.Utilities.dll! Line 43 + 0x5 bytes	Basic");
 
    [Fact, WorkItem("http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/537895")]
    public Task EmbededStatement1()
        => AssertFormatAsync("""
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            class Program
            {
                static void Main(string[] args)
                {
                    #region Myregion
                    int a;
                    if (true)
                        a++;
                    #endregion
                }
            }
            """, """
            using System;
            using System.Collections.Generic;
            using System.Linq;
 
            class Program
            {
                static void Main(string[] args)
                {
                    #region Myregion
                    int a;
                    if (true)
                        a++;
                        #endregion
                }
            }
            """);
 
    [Fact]
    public Task RefKeywords()
        => AssertFormatAsync("""
            class C
            {
                static void Main(string[] args)
                {
                    int i = 1;
                    TypedReference tr = __makeref(i);
                    Type t = __reftype(tr
                        );
                    int j = __refvalue(tr,
                        int
                        );
                }
            }
            """, """
            class C 
            {
                static void Main(string[] args)
                {
                    int i = 1;
                    TypedReference tr = __makeref(   i );
                    Type t = __reftype( tr 
                        );
                    int j = __refvalue(            tr  ,
                        int
                        );
                }
            }
            """);
 
    [Fact]
    public void NewLineOptions_LineFeedOnly()
    {
        using var workspace = new AdhocWorkspace();
        var tree = SyntaxFactory.ParseCompilationUnit("class C\r\n{\r\n}");
 
        // replace all EOL trivia with elastic markers to force the formatter to add EOL back
        tree = tree.ReplaceTrivia(tree.DescendantTrivia().Where(tr => tr.IsKind(SyntaxKind.EndOfLineTrivia)), (o, r) => SyntaxFactory.ElasticMarker);
 
        var options = new CSharpSyntaxFormattingOptions()
        {
            LineFormatting = new() { NewLine = "\n" }
        };
 
        var formatted = Formatter.Format(tree, workspace.Services.SolutionServices, options, CancellationToken.None);
 
        var actual = formatted.ToFullString();
        Assert.Equal("class C\n{\n}", actual);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/4019")]
    public void FormatWithTabs()
    {
        var code = """
            #region Assembly mscorlib
            // C:\
            #endregion
 
            using System.Collections;
 
            class F
            {
                string s;
            }
            """;
        var tree = SyntaxFactory.ParseCompilationUnit(code);
        var newLine = Environment.NewLine;
 
        tree = tree.ReplaceTokens(tree.DescendantTokens(descendIntoTrivia: true)
                                      .Where(tr => tr.IsKind(SyntaxKind.EndOfDirectiveToken)), (o, r) => o.WithTrailingTrivia(o.LeadingTrivia.Add(SyntaxFactory.ElasticEndOfLine(newLine)))
                                                                                                          .WithLeadingTrivia(SyntaxFactory.TriviaList())
                                                                                                          .WithAdditionalAnnotations(SyntaxAnnotation.ElasticAnnotation));
 
        using var workspace = new AdhocWorkspace();
 
        var options = new CSharpSyntaxFormattingOptions()
        {
            LineFormatting = new() { UseTabs = true, NewLine = newLine }
        };
 
        var formatted = Formatter.Format(tree, workspace.Services.SolutionServices, options, CancellationToken.None);
 
        var actual = formatted.ToFullString();
        Assert.Equal("""
            #region Assembly mscorlib
            // C:\
            #endregion
 
            using System.Collections;
 
            class F
            {
            	string s;
            }
            """, actual);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39351")]
    public Task SingleLineComment_AtEndOfFile_DoesNotAddNewLine()
        => AssertNoFormattingChangesAsync("""
            class Program { }
 
            // Test
            """);
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39351")]
    public Task MultiLineComment_AtEndOfFile_DoesNotAddNewLine()
        => AssertNoFormattingChangesAsync("""
            class Program { }
 
            /* Test */
            """);
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/39351")]
    public Task DocComment_AtEndOfFile_DoesNotAddNewLine()
        => AssertNoFormattingChangesAsync("""
            class Program { }
 
            /// Test
            """);
}