2016-09-12 4 views
5

以下のコードでは、 "Console.WriteLine"コールには "System" using命令が必要です。私はすでに "using System"のUsingDirectiveSyntaxオブジェクトと "Console.Writeline"のInvocationExpressionSyntaxオブジェクトを持っています。しかし、InvocationExpressionSyntaxオブジェクトとUsingDirectiveSyntaxオブジェクトが互いに属していることを、Roslynを使ってどのように知ることができますか?InvocationExpressionSyntaxに属しているUsingDirectiveSyntaxを見つけよう

using System;  
public class Program 
{ 
    public static void Main() 
    { 
     Console.WriteLine("Hello World"); 
    } 
} 
+1

私はあなたの構文木に何かを見つけるだろうとは思いません - 特定のクラス 'Console'がどのようなクラスを参照するかが決まる前に、セマンティクスが適用されている必要があります。 –

+0

確かに、両方のSymbolオブジェクトがある場合でも、どのようにリンクできますか? – TWT

答えて

4

InvocationExpressionSyntaxの方法記号は1つがあなたがusingディレクティブのシンボルを取得から取得する名前空間のシンボルに等しくなければならないことを、メンバーContainingNamespaceを持っています。その意味はNameメンバを意味モデルのクエリの開始点として使用することです。これはUsingDirectiveSyntax全体があなたに記号を与えないからです。

Try this LINQPad query(またはコンソールプロジェクトにコピー)、およびクエリの最後の行にtrueを取得します。)

// create tree, and semantic model 
var tree = CSharpSyntaxTree.ParseText(@" 
    using System; 
    public class Program 
    { 
     public static void Main() 
     { 
      Console.WriteLine(""Hello World""); 
     } 
    }"); 
var root = tree.GetRoot(); 

var mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); 
var compilation = CSharpCompilation.Create("SO-39451235", syntaxTrees: new[] { tree }, references: new[] { mscorlib }); 
var model = compilation.GetSemanticModel(tree); 

// get the nodes refered to in the SO question 

var usingSystemDirectiveNode = root.DescendantNodes().OfType<UsingDirectiveSyntax>().Single(); 
var consoleWriteLineInvocationNode = root.DescendantNodes().OfType<InvocationExpressionSyntax>().Single(); 

// retrieve symbols related to the syntax nodes 

var writeLineMethodSymbol = (IMethodSymbol)model.GetSymbolInfo(consoleWriteLineInvocationNode).Symbol; 
var namespaceOfWriteLineMethodSymbol = (INamespaceSymbol)writeLineMethodSymbol.ContainingNamespace; 

var usingSystemNamespaceSymbol = model.GetSymbolInfo(usingSystemDirectiveNode.Name).Symbol; 

// check the namespace symbols for equality, this will return true 

namespaceOfWriteLineMethodSymbol.Equals(usingSystemNamespaceSymbol).Dump(); 
関連する問題