2016-09-12 1 views
5

Dans le code ci-dessous, l'appel "Console.WriteLine" nécessite la directive "System" using pour fonctionner. J'ai déjà un objet UsingDirectiveSyntax pour "using System" et un objet InvocationExpressionSyntax pour "Console.Writeline". Mais comment puis-je savoir, en utilisant Roslyn, que les objets InvocationExpressionSyntax et UsingDirectiveSyntax appartiennent les uns aux autres?Rechercher UsingDirectiveSyntax qui appartient à InvocationExpressionSyntax

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

Je ne pense pas que vous pouvez trouver quoi que ce soit dans l'arbre de syntaxe - vous auriez besoin de la sémantique appliquée avant de décider à quelle classe spécifique 'Console' fait référence. –

+0

Oui, en effet, mais même quand j'ai l'objet Symbol des deux, comment puis-je les lier? – TWT

Répondre

4

Le symbole de la méthode du InvocationExpressionSyntax a un membre ContainingNamespace, que l'on devrait égaler le symbole d'espace de noms que vous obtenez de récupérer le symbole de la directive à l'aide. L'astuce consiste à utiliser le membre Name comme point de départ pour interroger le modèle sémantique, puisque l'entier UsingDirectiveSyntax ne vous donnera pas de symbole.

Try this LINQPad query (ou le copier dans un projet de console), et vous obtiendrez true sur la dernière ligne de la requête;)

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