单步执行Roslyn C#编译器

dha*_*ech 7 c# roslyn

我已经构建了如此处所述的Roslyn源代码.

我想在C#编译器中添加一个断点,并逐步完成这个简单程序的补充:

using System;

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

            Console.WriteLine(result);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我应该在哪里设置断点?它应该在编译过程的早期,因为我想逐步解析甚至是lexing.

如果我将CompilerExtension设置为启动项目并按F5(开始调试),则会启动运行新构建的编译器的Visual Studio副本.我想避免每次我想要逐步完成编译器时都启动一个新的Visual Studio实例.设置一个直接在上面的源上调用编译器代码的小程序有什么好方法?

dha*_*ech 5

以下是Josh在上述评论中提出的一种方法.

  • 向Roslyn解决方案添加一个新的"控制台应用程序"项目.

  • 将这两个引用添加到项目中:

在此输入图像描述

一个测试解析器的简单程序:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 在要调用的行中添加断点ParseText.

  • "开始调试"并进入该行以深入研究解析器.

一个简单的程序来测试编译器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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)