Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find UsingDirectiveSyntax that belongs to InvocationExpressionSyntax

In the code below, the "Console.WriteLine" call needs the "System" using directive to work. I already have a UsingDirectiveSyntax object for "using System" and an InvocationExpressionSyntax object for "Console.Writeline". But how can I know, using Roslyn, that the InvocationExpressionSyntax and UsingDirectiveSyntax objects belong to each other?

using System;       
public class Program
{
   public static void Main()
   {
      Console.WriteLine("Hello World");
   }
}
like image 943
TWT Avatar asked Sep 12 '16 13:09

TWT


1 Answers

The method symbol of the InvocationExpressionSyntax has a member ContainingNamespace, that one should equal the namespace symbol that you get from retrieving the symbol of the using directive. The trick there is to use the Name member as starting point for querying the semantic model, since the entire UsingDirectiveSyntax won't give you a symbol.

Try this LINQPad query (or copy it into a console project), and you'll get true on the last line of the query ;)

// 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();
like image 193
Ties Avatar answered Sep 28 '22 03:09

Ties