本文介绍了如何在ReSharper插件中创建一个表示封闭泛型类型的`ITypeElement`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ReSharper 8 sdk并希望找到特定通用接口的所有继承者,其中通用类型是特定类型。我有,这个问题大部分都在那里,但我只能找到 ICommandHandler< T> 不是我想要的一个实现, ICommandHandler< TestCommand>



这是我有的代码:

  foreach(declaredElement.GetPsiServices()中的var psiModule)模块。 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();






$ b

如果我在此行之后提示commandHandlerType:



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

我看到该类型被正确指定:





但是当我从这个类型获得 ITypeElement 传入我的搜索时使用这一行

  var handlerTypeelement = commandHandlerType.GetTypeElement(); 

我似乎已经失去了这种类型:





search找到 ICommandHandler< T> 的所有实现。

所以我的问题是,如何创建 ITypeElement 它代表了我想搜索的封闭泛型类型?



或者:我如何搜索返回的集合继承者的类型,它有我开始的类作为泛型类型参数?

解决方案

啊,这是有道理的。一个 ITypeElement IDeclaredElement 的一个实例,这意味着它有一个声明 - 例如类或接口声明。所以,当你得到一个代表你的封闭泛型的 IType 时,它由代表泛型类型的 ITypeElement ICommandHandler )和一个 ISubstitution ,它表示已解析的泛型类型参数( AnotherCommand )。当您调用 IType.GetTypeElement()时,它将返回类型元素/替换对的类型元素部分,这是开放式通用声明元素(因为接口声明可以我认为你可能不得不采取另一种方法,并找到 ITypeHandler< T>的所有继承者(实现者)。 并在消费者中将其过滤掉。传递给使用者的 FindResult 可以向下转换为 FindResultInheritedElement ,这会给你一个声明的元素来表示类实现 ITypeHandler< T> 。您应该能够遍历这些元素的接口以查看它们实现的内容,并且只接受实现正确 T 的查找结果。我认为 TypeElementUtil 在这里可以帮助获取声明元素的所有超类型(基类型+接口)。


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?

解决方案

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.

这篇关于如何在ReSharper插件中创建一个表示封闭泛型类型的`ITypeElement`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-05 09:17