从解析源外声明的类型标识符中获取SymbolInfo

时间:2017-03-08 08:58:43

标签: c# .net roslyn

我想使用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,以及引用的其他类型。

  • 如何从IdentifierNameSyntax获取SymbolInfo,以获取在解析源外声明的类型?
  • 有没有办法从using语句构造SemanticModel?

2 个答案:

答案 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>();