2017-03-08 69 views
0

我想使用Roslyn來解析C#代碼,並且我想要獲取代碼中每個引用類型的限定名稱。從已解析源以外聲明的類型標識符獲取SymbolInfo

例如說我想分析這個代碼片段:

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); 
    } 
} 

在這個例子中,當我到了IdentifierNameSyntax描述「String」,info.Symbol將爲null。我想通過一些方法來知道全名System.String,並且與其他引用的類型相同。

  • 如何從IdentifierNameSyntax中爲解析源之外聲明的類型獲取SymbolInfo?
  • 有沒有一種方法從using語句構造SemanticModel?
+0

使用'.OfType ()',並使用'info.Symbol.ToString()'。 – SLaks

回答

3

您的實際問題是沒有String類型。

如果您查看SemanticModel中的編譯錯誤,您將看到此錯誤。

您需要在您的Compilation中添加對mscorlib的引用,以便存在System.String。 一旦你這樣做,info.Symbol將不會爲空。

+0

謝謝,我補充說: 'MetadataReference reference = MetadataReference.CreateFromFile(typeof(string).Assembly.Location);' 並解決了我的例子。有沒有從所有使用語句中創建MetadataReferences的實用方法? – Findus

相關問題