2016-09-12 9 views
5

W poniższym kodzie wywołanie "Console.WriteLine" wymaga "Systemu" używającego dyrektywy do działania. Mam już obiekt UsingDirectiveSyntax dla "using System" i obiektu InvocationExpressionSyntax dla "Console.Writeline". Ale skąd mogę wiedzieć, używając Roslyn, że obiekty InvocationExpressionSyntax i UsingDirectiveSyntax należą do siebie?Znajdź UsingDirectiveSyntax należący do InvocationExpressionSyntax

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

Nie sądzę, że można znaleźć coś w drzewie składni - potrzebujesz semantyki zastosowanej zanim zdecydujesz, do której konkretnej klasy 'Console' się odnosi. –

+0

Tak, rzeczywiście, ale nawet gdy mam obiekt Symbol obu, jak mogę je połączyć? – TWT

Odpowiedz

4

metoda Symbolem InvocationExpressionSyntax ma człon ContainingNamespace, że trzeba równać symbol przestrzeni nazw, które można uzyskać z pobierania symbol używając dyrektywy. Sztuczka polega na użyciu elementu Name jako punktu wyjścia do sprawdzania modelu semantycznego, ponieważ cały kod UsingDirectiveSyntax nie daje symbolu.

Try this LINQPad query (lub skopiować go do projektu konsoli), a dostaniesz true na ostatniej linii zapytania;)

// 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();