2016-03-05 48 views
7

我已将Roslyn源代码构建为described here单步执行Roslyn C#编译器

我想在C#编译器添加断点,通过这个简单程序的compliation步骤:

using System; 

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

      Console.WriteLine(result); 
     } 
    } 
} 

我应该在哪里设置断点?它应该在编译过程的早期,因为我希望通过解析甚至是轻松一步。

如果我将CompilerExtension设置为启动项目并按F5(启动调试),将启动运行新建的编译器的Visual Studio副本。我想避免每次想要遍历编译器都必须启动Visual Studio的新实例。什么是设置一个小程序的好方法,它直接调用上述源代码中的编译器代码?

+5

您可以添加一个新项目到Roslyn解决方案,添加对正确的Microsoft.CodeAnalysis项目的引用,然后调用'CSharpSyntaxTree.ParseText()'和'Compilation.Emit()'。然后,您可以逐步浏览您感兴趣的解析或发布代码。 – JoshVarty

+0

感谢Josh!我添加了一个演示'ParseText'的答案。 @JoshVarty – dharmatech

+1

我写了一篇博客文章,有点基于@JoshVarty在这里和他的博客文章中的建议。对于任何想要与Roslyn内部玩家一起玩的人来说,这可能是有趣的。 https://renniestechblog.com/information/33-modifying-roslyn-step-1-initial-test – RenniePet

回答

5

乔希在上面的评论中提出了一种方法。

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

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

enter image description here

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

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); 
     } 
    } 
} 
  • 添加断点的行请致电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()); 
     } 
    } 
} 
+1

对于当前版本的Roslyn和Visual Studio 2017,您还需要添加对System.Reflection的NuGet包的引用。元数据,版本= 1.4.2。直到我确定(并花了我很长时间),我才得到“应用程序处于中断模式”,并且根本无法做任何事情。这可能是由于Visual Studio中的一个错误https://developercommunity.visualstudio.com/content/problem/104485/the-application-is-in-break-mode-1.html什么最终提供了真正问题的线索当我双击生成的.exe文件时 - 然后在控制台窗口中出现错误。 – RenniePet

2

如果你想有一个简单的程序,调用编译器,就可以考虑使用CSC为启动项目。您可以指定参数从项目的调试设置传递(如源文件)。

+0

谢谢杰森!我目前正在探讨乔希在上面评论中提到的方法。目前它似乎运作良好。我已经添加了一个描述该方法的答案。 – dharmatech

+0

这似乎是在Visual Studio调试器下测试Roslyn编译器的合理方法。但是csc.exe有很多可能的参数。你有链接或建议需要哪些参数,哪些额外的参数可能是一个好主意,以及使用? – RenniePet