简体   繁体   中英

Stepping through the Roslyn C# compiler

I've built the Roslyn source as described here .

I'd like to add a breakpoint in the C# compiler and step through the compliation of this simple program:

using System;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = 1 + 2;

            Console.WriteLine(result);
        }
    }
}

Where should I set a breakpoint? It should be early in the compilation process as I'd like to step through parsing and even lexing.

If I set CompilerExtension as the startup project and hit F5 (Start Debugging), a copy of Visual Studio is launched running the newly built compiler. I'd like to avoid having to launch a new instance of Visual Studio each time I'd like to step through the compiler. What's a good way to setup a small program which invokes the compiler code on the above source directly?

Here's one approach as suggested by Josh in a comment above.

  • Add a new "Console Application" project to the Roslyn solution.

  • Add these two references to the project:

在此输入图像描述

A simple program to test the parser:

using Microsoft.CodeAnalysis.CSharp;

namespace TestCompiler
{
    class Program
    {
        static void Main(string[] args)
        {
            var program_text = @"

                using System;

                namespace ConsoleApplication2
                {
                    class Program
                    {
                        static void Main(string[] args) 
                        { var result = 2 + 3; Console.WriteLine(result); }
                    }
                }
            ";

            var result = CSharpSyntaxTree.ParseText(program_text);
        }
    }
}
  • Add a breakpoint to the line that calls ParseText .

  • "Start Debugging" and step into that line to delve into the parser.

A simple program to test the compiler via Emit :

using System;
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace TestCompiler
{
    class Program
    {
        static void Main(string[] args)
        {
            var program_text = @"

                using System;

                namespace ConsoleApplication2
                {
                    class Program
                    {
                        static void Main(string[] args) 
                        { var result = 2 + 3; Console.WriteLine(result); }
                    }
                }
            ";

            var syntax_tree = CSharpSyntaxTree.ParseText(program_text);

            var compilation = CSharpCompilation.Create(
                Guid.NewGuid().ToString("D"),
                new[] { syntax_tree },
                new[] { MetadataReference.CreateFromFile(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll") });

            var emit_result = compilation.Emit(new MemoryStream());
        }
    }
}

If you want to have a simple program that invokes the compiler, just consider using csc as your startup project. You can specify the arguments to pass (like source files) from the debug settings on the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM