How do I create an "ITypeElement" with a presented private generic type in a ReSharper plugin?
I am using SDK ReSharper 8 and want to find all inheritance of a specific generic interface where generic type is special type. I have a more general question asked that got most of the way, but I can find any implementation ICommandHandler<T>
, not one of the implementations 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 after this line tooltip commandHandlerType:
var commandHandlerType = TypeFactory.CreateType (genericTypeElement, theType);
I see that the type is correct:
But then when I get ITypeElement
from this type to go to my search using this line
var handlerTypeelement = commandHandlerType.GetTypeElement();
I seem to have lost the type:
And so my search finds all the implementations ICommandHandler<T>
.
So my question is, how do I create ITypeElement
that represents the private type that I want to find?
Or alternatively: how can I find the returned collection of inheritors for the type in which class I was started as a parameter of the type type?
source to share
Oh, that makes sense. ITypeElement
is an instance IDeclaredElement
, which means something that has a declaration, such as a class or interface declaration. So when you get IType
which your private generic represents, it consists of ITypeElement
that that represents the generic type ( ICommandHandler
) and ISubstitution
that that represents the allowed type parameters ( AnotherCommand
). When you call IType.GetTypeElement()
, it returns the element type part of the element / type substitution pair that is the publicly declared declared element (since an interface declaration can only ever be exposed).
I think you might have to take an alternative approach and find all the descendants (developers) ITypeHandler<T>
and filter them from the consumer. FindResult
passed to consumer can be turned off before FindResultInheritedElement
, which will provide you with a declared element that represents the class that implements ITypeHandler<T>
. You should be able to traverse the interfaces of those elements to see what they implement and only accept search results that implement the correct one T
. I think it TypeElementUtil
helps here to get all the super-types (base types + interfaces) of the declared element.
source to share