How do I create a `ITypeElement` with represents a closed generic type in a ReSharper plugin?

随声附和 提交于 2019-12-13 02:35:15

问题


I'm using the ReSharper 8 sdk and want to find all inheritors of a particular generic interface, where the generic type is a particular type. I have asked a more general question which got most of the way there, but I am only able to find any implementation of ICommandHandler<T> and not the one implementation I want, ICommandHandler<TestCommand>

this is the code I have:

foreach (var psiModule in declaredElement.GetPsiServices().Modules.GetModules())
{
    IDeclaredType genericType = TypeFactory.CreateTypeByCLRName("HandlerNavigationTest.ICommandHandler`1", psiModule, theClass.ResolveContext);
    var genericTypeElement = genericType.GetTypeElement();
    if (genericTypeElement != null)
    {                    
        var theType = TypeFactory.CreateType(originalTypeElement);
        var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
        var handlerTypeelement = commandHandlerType.GetTypeElement();
        solution.GetPsiServices().Finder.FindInheritors(handlerTypeelement, searchDomainFactory.CreateSearchDomain(solution, true),
        inheritorsConsumer, NullProgressIndicator.Instance);
        var inheritedInstance= inheritorsConsumer.FoundElements.First();
        var sourceFile = inheritedInstance.GetSourceFiles().First();
    }
}  

if I tooltip the commandHandlerType after this line:

var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);

I see that the type is correctly specified:

But then when I get the ITypeElement from this type to pass into my search using this line

var handlerTypeelement = commandHandlerType.GetTypeElement();

I seem to have lost the type:

And so my search finds all implementations of the ICommandHandler<T>.

So my question is, how do I create the ITypeElement which represents the closed generic type I want to search for?

Or alternatively: How can I search the returned collection of inheritors for the type which has the class I started with as the generic type parameter?


回答1:


Ah, that makes sense. An ITypeElement is an instance of IDeclaredElement, which means it's something that has a declaration - such as a class or interface declaration. So when you get an IType that represents your closed generic, it's made up of an ITypeElement that represents the generic type (ICommandHandler) and an ISubstitution that represents the resolved generic type parameters (AnotherCommand). When you call IType.GetTypeElement(), it will return the type element part of the type element/substitution pair, which is the open generic declared element (because an interface declaration can only ever be open).

I think you might have to take the alternative approach, and find all inheritors (implementors) of ITypeHandler<T> and filter them down in the consumer. The FindResult passed to the consumer can be downcast to a FindResultInheritedElement, which will give you a declared element that represents the class that implements ITypeHandler<T>. You should be able to walk these elements' interfaces to see what they implement, and only accept those find results that implement the correct T. I think TypeElementUtil will help here to get all super types (base types + interfaces) of the declared element.



来源:https://stackoverflow.com/questions/31044308/how-do-i-create-a-itypeelement-with-represents-a-closed-generic-type-in-a-resh

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!