C# Roslyn Compiler - How to get namespace of a type from IdentifierNameSyntax?

Viewed 2833

Suppose I have a call in the code, SomeClass.SomeStaticMethod<T>(), which is an InvocationExpressionSyntax.

I get name of the generic type T as string (from IdentifierNameSyntax). I tried to get Symbol of T but I did not succeed.

How can I find out the namespace information of type T?

UPDATE: @SJP's answer is correct. I want to explain my mistake for those who want to get namespace information from IdentifierNameSyntax, which contains an identifier for a class (class name):

My initial aim was to find invocations in SomeClass.SomeMethod<T>() format and get namespace information of type T.

var namedTypeSymbol = context.Symbol as INamedTypeSymbol;
var reference = nameTypeSymbol.DeclaringSyntaxReferences.First();
var classSyntaxTree = reference.SyntaxTree;

var semanticModel = context.Compilation.GetSemanticModel(classSyntaxTree);
var genericNameSyntax = (GenericNameSyntax)((MemberAccessExpressionSyntax)node.Expression).Name;
var identifierNameSyntax = genericNameSyntax.TypeArgumentList.Arguments.First();
var typeInfo = semanticModel.GetTypeInfo(identifierNameSyntax);
var nameSpace = ((INamedTypeSymbol)typeInfo.Type).ContainingNamespace;
var nameSpaceName = nameSpace.ToString();

Here is my mistake:

I tried to get full namespace like <module_name>.<namespace_part_1>.<namespace_part_2> but when I did namedTypeSymbol.ContainingNamespace.Name , I got only <namespace_part_2>. After couple of hours, I found that getting full namespace is done like namedTypeSymbol.ContainingNamespace.ToString().

Sometimes best thing to do is going outside and taking fresh air :)

2 Answers

A call to Function{SuppliedArgument}(...) is gonna have a GenericNameSyntax as the {SuppliedArgument}. Which isnt the same as a TypeDeclaration.TypeParameterList.Parameters. You can't get anything from those. Theyre placeholders. You need to go through the GenericNameSyntax.TypeArgumentList, and use SemanticModel.GetSymbolInfo(identifierNameSyntax).Symbol.ContainingNamespace on each to get the namespaces the identifiers are contained in.

Related