【发布时间】:2019-02-02 01:39:40
【问题描述】:
我正在试验 roslyn,解析和生成 c# 代码。我试图弄清楚CSharpSyntaxTree.ParseText 方法如何处理预处理器符号。
这是我的测试方法。它接受一些 C# 代码作为字符串,提取 using 语句并返回带有这些 using 语句的新字符串,同时考虑到预处理器指令。
private static string Process(string input, string[] preprocessorSymbols)
{
var options = CSharpParseOptions.Default.WithPreprocessorSymbols(preprocessorSymbols);
var syntaxTree = CSharpSyntaxTree.ParseText(input, options);
var compilationUnit = (CompilationUnitSyntax)syntaxTree.GetRoot();
var usings = compilationUnit.Usings.ToArray();
var cs = SyntaxFactory.CompilationUnit()
.AddUsings(usings)
.NormalizeWhitespace();
var result = cs.ToString();
return result;
}
当使用以下输入提供此方法时,它按预期工作:
var input = "using MyUsing1;\r\nusing MyUsing2;";
string result = Process(input, new[] { "" });
Assert.AreEqual("using MyUsing1;\r\nusing MyUsing2;", result);
当添加预处理器指令,但没有将所述指令传递给解析器时,结果仍然如预期(条件using 语句被剥离):
var input =
"using MyUsing1;\r\n" +
"#if CONDITIONAL\r\n" +
"using MyUsing2;\r\n" +
"#endif";
string result = Process(input, new[] { "" });
Assert.AreEqual("using MyUsing1;", result);
但是,当将 CONDITIONAL 预处理器指令添加到 CSharpParseOptions 时,我得到了一个奇怪的结果
var input =
"using MyUsing1;\r\n" +
"#if CONDITIONAL\r\n" +
"using MyUsing2;\r\n" +
"#endif";
string result = Process(input, new[] { "CONDITIONAL" });
Assert.AreEqual("using MyUsing1;\r\nusing MyUsing2;", result); // fails??
实际返回值为"using MyUsing1;\r\n#if CONDITIONAL\r\nusing MyUsing2;"。 #if CONDITIONAL 部分被保留,#endif 被删除。
这是一个错误,还是我做错了什么?
【问题讨论】:
-
你看过LINQPad吗,它可以显示脚本的语法树。