Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we get System.Type from Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax?

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.

like image 372
WSK Avatar asked Mar 14 '23 07:03

WSK


1 Answers

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).

like image 51
JoshVarty Avatar answered Apr 06 '23 06:04

JoshVarty