我想使用Roslyn来解析C#代码,我希望在代码中获得每个引用类型的限定名称。
比如说我想解析这段代码:
using System;
namespace RoslynTest
{
public class Test
{
public static void Main()
{
String a = "Hello, World!";
Console.WriteLine(a);
}
}
}
要解析它,我使用以下代码:
SyntaxTree tree = CSharpSyntaxTree.ParseText(source);
CSharpCompilation compilation = CSharpCompilation.Create("test", new[] { tree });
SemanticModel semanticModel = compilation.GetSemanticModel(tree, false);
CompilationUnitSyntax root = (CompilationUnitSyntax)tree.GetRoot();
IEnumerable<IdentifierNameSyntax> identifiers = root.DescendantNodes()
.Where(s => s is IdentifierNameSyntax)
.Cast<IdentifierNameSyntax>();
foreach (IdentifierNameSyntax i in identifiers)
{
SymbolInfo info = semanticModel.GetSymbolInfo(i);
if (info.Symbol == null)
{
Console.WriteLine("Unknown :(");
}
else
{
Console.WriteLine(info.Symbol.ContainingNamespace?.Name + "." + info.Symbol.ContainingType?.Name + "." + info.Symbol.Name);
}
}
在这个例子中,当我到达描述“String”的IdentifierNameSyntax时,info.Symbol将为null。我想通过某种方式知道全名System.String,以及引用的其他类型。
答案 0 :(得分:3)
您的实际问题是没有String
类型。
如果你查看SemanticModel中的编译错误,你会看到一个错误。
您需要在Compilation
中添加对mscorlib的引用,以便System.String
存在。
完成后,info.Symbol
将不为空。
答案 1 :(得分:0)
另外,只需追逐为:
IEnumerable<IdentifierNameSyntax> identifiers =
root.DescendantNodes().OfType<IdentifierNameSyntax>();
而不是:
IEnumerable<IdentifierNameSyntax> identifiers = root.DescendantNodes()
.Where(s => s is IdentifierNameSyntax)
.Cast<IdentifierNameSyntax>();