Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn - Is symbol implementation of interface?

Is it possible to know with Roslyn if a Symbol is the implementation of something in an interface? For example Dispose() in IDisposable?

I have a symbol that represents the Dispose() method, but as far as I can see there is no property that indicates that it's an implementation of a method that is defined by the IDisposable interface.

like image 482
TWT Avatar asked Feb 06 '17 18:02

TWT


2 Answers

Sure its possible.

Just for your Dispose example:

var disposeMethodSymbol = ...
var type = disposeMethodSymbol.ContainingType;
var isInterfaceImplementaton = type.FindImplementationForInterfaceMember(
            type.Interfaces.Single().
            GetMembers().OfType<IMethodSymbol>().Single()) == disposeMethodSymbol ;

But if it for general use you need to write it more generally, use AllInterfaces and not Interfaces and sure not use Single.

Example:

public static bool IsInterfaceImplementation(this IMethodSymbol method)
{
    return method.ContainingType.AllInterfaces.SelectMany(@interface => @interface.GetMembers().OfType<IMethodSymbol>()).Any(interfaceMethod => method.ContainingType.FindImplementationForInterfaceMember(interfaceMethod).Equals(method));
}
like image 192
Dudi Keleti Avatar answered Oct 07 '22 13:10

Dudi Keleti


You may find useful this set of extension methods from Roslyn: http://sourceroslyn.io/#Microsoft.CodeAnalysis.Workspaces/ISymbolExtensions.cs,93

Particularly this one ExplicitOrImplicitInterfaceImplementations method:

public static ImmutableArray<ISymbol> ExplicitOrImplicitInterfaceImplementations(this ISymbol symbol)
{
    if (symbol.Kind != SymbolKind.Method && symbol.Kind != SymbolKind.Property && symbol.Kind != SymbolKind.Event)
        return ImmutableArray<ISymbol>.Empty;

    var containingType = symbol.ContainingType;
    var query = from iface in containingType.AllInterfaces
                from interfaceMember in iface.GetMembers()
                let impl = containingType.FindImplementationForInterfaceMember(interfaceMember)
                where symbol.Equals(impl)
                select interfaceMember;
    return query.ToImmutableArray();
}
like image 33
SENya Avatar answered Oct 07 '22 12:10

SENya