简体   繁体   中英

Get exact definition of function from invocation which is defined in interface but implemented at multiple locations in C# using Roslyn

I saw there are lots of questions asked on this topic (C#, Roslyn, Find References and Definitions). But I still not got answer for what I want. Here is explanations. I have interface:

public interface IRepository {      
    IEnumerable<X> Abc(long customerIdentity, ...);        
}                        

Now, this interface in implemented by on class like:

public abstract class RepositoryBase : IRepository {
 public virtual IEnumerable<X> Abc(long customerIdentity, long? associatedOrderIdentity, ...) { ... }      
}

Since this is abstract class, then other classes may have redefined this method as this method is virtual. Also, interface can have property with other interface as well.

public sealed class CustRepository : RepositoryBase {
   public override IEnumerable<X> Abc(long customerIdentity, long? associatedOrderIdentity, ...){ ... }       
}

Another thing is here like this

public interface IRepositoryManager { 
    IRepository Repository { get; }
}

In my class variable is declared like this: private IRepositoryManager _repositoryManager; and I can call method like this: this._repositoryManager.Repository.Abc(customerIdentity, ...)

Here are my questions now.

  1. How I get to know which method it will call at run time?. I want this to get the definition/declaration using Roslyn. I can use invocation expression to get this statement.
  2. Should I take method from base class which directly implements the interface. Or do I need to see definitions from inheritance chain?.

I found some useful answers from: here and here: here

Please do not close this question as I'm really struggling to get this answer. Thanks in advance!! .

Currently I have this code to get some of information using Roslyn API's.

var syntaxTree = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
                    var sm = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
                    var semantic = compilation.GetSemanticModel(sm);
                    var invocations = (from d in syntaxTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>() select d).ToList();
                    foreach (var invocation in invocations)
                    {
                        // if (!invocation.Expression.ToString().Contains("FindAlertsByLimit") && !invocation.Expression.ToString().Contains("FindAlertsByWindow")) continue;
                        var ms = semantic.GetSymbolInfo(invocation).Symbol;
                        if (ms == null) continue;
                        var referencesTo = await SymbolFinder.FindReferencesAsync(ms, document.Project.Solution).ConfigureAwait(false);
                        Console.WriteLine(referencesTo);
                        var de = SymbolFinder.FindDeclarationsAsync(project, referencesTo.First().Definition.Name, false, SymbolFilter.Member).ConfigureAwait(false).GetAwaiter().GetResult().ToList();
                        Console.WriteLine(de);
                        // other approach
                        IMethodSymbol methodSymbol = semantic.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
                        if (methodSymbol == null) continue;
                        var syntaxReferences = methodSymbol.DeclaringSyntaxReferences.ToList();
                        if (!syntaxReferences.Any()) continue;
                        var declaration = syntaxReferences.First().GetSyntax();
                        var semanticModel = compilation.GetSemanticModel(declaration.SyntaxTree);
                        Console.WriteLine(semanticModel.SyntaxTree.FilePath);
}

But seems like I'm not getting exact method definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM