我已经构建了如此处所述的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实例.设置一个直接在上面的源上调用编译器代码的小程序有什么好方法?
以下是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)