Jan Kowalski
Jan Kowalski

Reputation: 193

How can I obtain return type from method passed as an argument in another method with Roslyn?

Lets say that I have a code:

public class Test {
    private readonly IFactory _factory;
    private readonly ISomeClass _someClass;

    public Test(IFactory factory, ISomeClass someClass)
    {
        _factory = factory;
        _someClass = someClass;
    }

    ....

    public void TestMethod() {
        _someClass.Do(_factory.CreateSomeObject());
    }
}

public class Factory {
    public SomeObject CreateSomeObject() {
        return new SomeObject();
    }
}

public class SomeClass {
    public void Do(SomeObject obj){
        ....
    }
}

I would like to get return type of CreateSomeObject from InvocationExpressionSyntax of someClass.Do(_factory.CreateSomeObject()); Is it possible?

I have a list of arguments (ArgumentSyntax) but I have no clue how to get method return type from ArgumentSyntax. Is there better and easier way to do it other then scanning a solution for Factory class and analyzing CreateSomeObject method?

Upvotes: 0

Views: 1017

Answers (1)

Janez Lukan
Janez Lukan

Reputation: 1449

Yes, it is possible. You would need to use Microsoft.CodeAnalysis.SemanticModel for it.

I assume you have CSharpCompilation and SyntaxTree already available, so you would go in your case with something like this:

SemanticModel model = compilation.GetSemanticModel(tree);           
var methodSyntax = tree.GetRoot().DescendantNodes()
    .OfType<MethodDeclarationSyntax>()
    .FirstOrDefault(x => x.Identifier.Text == "TestMethod");
var memberAccessSyntax = methodSyntax.DescendantNodes()
    .OfType<MemberAccessExpressionSyntax>()
    .FirstOrDefault(x => x.Name.Identifier.Text == "CreateSomeObject");
var accessSymbol = model.GetSymbolInfo(memberAccessSyntax);
IMethodSymbol methodSymbol = (Microsoft.CodeAnalysis.IMethodSymbol)accessSymbol.Symbol;
ITypeSymbol returnType = methodSymbol.ReturnType;

Once you get the desired SyntaxNode out of the semantic model, you need to get its SymbolInfo and properly cast it, to get its ReturnType which does the trick.

Upvotes: 2

Related Questions