6

Can we get System.Type or essentially fully qualified type name from Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax? Problem is, TypeSyntax returns the name of the type as it was written in code that may not be fully a qualified class name, we can't find Type from it.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
WSK
  • 5,949
  • 8
  • 49
  • 74
  • 1
    Note you can't easily get a System.Type, but you can get a Microsoft.CodeAnalysis.ITypeSymbol. Josh's answer already gives a great explanation about that. Note that System.Type isn't really what you want in most cases, because that means you have types loaded in your process in a way you don't want. – Jason Malinowski Oct 29 '15 at 18:57

1 Answers1

11

To get the fully qualified name of a piece of syntax, you need to use the SemanticModel to gain access to its symbol. I've written a guide to the semantic model on my blog: Learn Roslyn Now: Introduction to the Semantic Model

Based on your previous question, I'm assuming you're looking at fields.

var tree = CSharpSyntaxTree.ParseText(@"
class MyClass
{
    int firstVariable, secondVariable;
    string thirdVariable;
}");

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

//Get the semantic model
//You can also get it from Documents
var model = compilation.GetSemanticModel(tree);

var fields = tree.GetRoot().DescendantNodes().OfType<FieldDeclarationSyntax>();
var declarations = fields.Select(n => n.Declaration.Type);
foreach (var type in declarations)
{
    var typeSymbol = model.GetSymbolInfo(type).Symbol as INamedTypeSymbol;
    var fullName = typeSymbol.ToString();
    //Some types like int are special:
    var specialType = typeSymbol.SpecialType;
}

You can also get the symbols for the declarations themselves (instead of for the types on the declarations) via:

var declaredVariables = fields.SelectMany(n => n.Declaration.Variables);
foreach (var variable in declaredVariables)
{
    var symbol = model.GetDeclaredSymbol(variable);
    var symbolFullName = symbol.ToString();
}

One final note: Calling .ToString() on these symbols gives you their fully qualified name, but not their fully qualified metadata name. (Nested classes have + before their class name and generics are handled differently).

Community
  • 1
  • 1
JoshVarty
  • 9,066
  • 4
  • 52
  • 80
  • 1
    For getting the metadata name I have a method [here](http://stackoverflow.com/a/27106959/73070), as to my knowledge there still is no publicly-accessible method for getting that in Roslyn. – Joey Oct 29 '15 at 19:05