Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn get IdentifierName in ObjectCreationExpressionSyntax

Currently I am working on simple code analyse for c# with roslyn. I need to parse all document of all projects inside one solution and getting the declared used classes inside this document.

For example from:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();
    }
}

I want to get Program uses Foo.

I already parse all documents and get the declared class inside.

// all projects in solution
foreach (var project in _solution.Projects)
{
    // all documents inside project
    foreach (var document in project.Documents)
    {
        var syntaxRoot = await document.GetSyntaxRootAsync();
        var model = await document.GetSemanticModelAsync();
        var classes = syntaxRoot.DescendantNodes().OfType<ClassDeclarationSyntax>();
        // all classes inside document
        foreach (var classDeclarationSyntax in classes)
        {
            var symbol = model.GetDeclaredSymbol(classDeclarationSyntax);
            var objectCreationExpressionSyntaxs = classDeclarationSyntax.DescendantNodes().OfType<ObjectCreationExpressionSyntax>();
            // all object creations inside document
            foreach (var objectCreationExpressionSyntax in objectCreationExpressionSyntaxs)
            {
                // TODO: Get the identifier value
            }
        }
    }
}

The problem is to get the IdentifierName Foo. Using the debugger, I see objectCreationExpressionSyntax.Typegot the Identifier.Text got the value I need, but objectCreationExpressionSyntax.Type.Identifierseems to be private.

I could use the SymbolFinder to find all references of a Class in the solution. As I already need to parse all documents its should work without.

Maybe I am on the wrong path? How to get the identifier value?

like image 670
Frank.Kubis Avatar asked Sep 16 '25 10:09

Frank.Kubis


1 Answers

You'll need to handle the different types of TypeSyntaxes. See here: http://sourceroslyn.io/#Microsoft.CodeAnalysis.CSharp/Syntax/TypeSyntax.cs,29171ac4ad60a546,references

What you see in the debugger is a SimpleNameSyntax, which does have a public Identifier property.

Update

var ns = objectCreationExpressionSyntax.Type as NameSyntax;
if (ns != null)
{
  return ns.Identifier.ToString();
}

var pts = objectCreationExpressionSyntax.Type as PredefinedTypeSyntax;
if (pts != null)
{
  return pts.Keyword.ToString();
}

... 

All other subtypes would need to be handed. Note that ArrayType.ElementType is also a TypeSyntax, so you would most probably need to make this method recursive.

like image 155
Tamas Avatar answered Sep 18 '25 09:09

Tamas