如何在 ReSharper 插件中创建代表封闭泛型类型的“ITypeElement”?
How do I create a `ITypeElement` with represents a closed generic type in a ReSharper plugin?
我正在使用 ReSharper 8 sdk 并希望找到特定泛型接口的所有继承者,其中泛型类型是特定类型。我有 大部分内容,但我只能找到 ICommandHandler<T>
的任何实现,而不是我想要的一个实现,ICommandHandler<TestCommand>
这是我的代码:
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();
}
}
如果我在这一行之后提示 commandHandlerType:
var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
我看到指定的类型是正确的:
但是当我从这种类型中得到 ITypeElement
并使用这一行
传递到我的搜索中时
var handlerTypeelement = commandHandlerType.GetTypeElement();
我好像输了类型:
所以我的搜索找到了 ICommandHandler<T>
.
的所有实现
所以我的问题是,如何创建代表我要搜索的封闭泛型类型的 ITypeElement
?
或者:如何在返回的继承者集合中搜索以 class 作为泛型类型参数的类型?
嗯,有道理。 ITypeElement
是 IDeclaredElement
的一个实例,这意味着它有一个声明——例如 class 或接口声明。因此,当您获得代表封闭泛型的 IType
时,它由代表泛型类型 (ICommandHandler
) 的 ITypeElement
和代表已解析泛型的 ISubstitution
组成类型参数 (AnotherCommand
)。当您调用 IType.GetTypeElement()
时,它将 return 类型 element/substitution 对的类型元素部分,这是开放的泛型声明元素(因为接口声明只能是开放的)。
我认为您可能必须采用替代方法,找到 ITypeHandler<T>
的所有继承者(实现者)并在消费者中过滤它们。传递给消费者的 FindResult
可以向下转换为 FindResultInheritedElement
,这将为您提供一个已声明的元素,该元素表示实现 ITypeHandler<T>
的 class。您应该能够遍历这些元素的接口以查看它们实现了什么,并且只接受那些实现正确 T
的查找结果。我认为 TypeElementUtil
将有助于获取已声明元素的所有超类型(基本类型 + 接口)。
我正在使用 ReSharper 8 sdk 并希望找到特定泛型接口的所有继承者,其中泛型类型是特定类型。我有 ICommandHandler<T>
的任何实现,而不是我想要的一个实现,ICommandHandler<TestCommand>
这是我的代码:
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();
}
}
如果我在这一行之后提示 commandHandlerType:
var commandHandlerType = TypeFactory.CreateType(genericTypeElement,theType);
我看到指定的类型是正确的:
但是当我从这种类型中得到 ITypeElement
并使用这一行
var handlerTypeelement = commandHandlerType.GetTypeElement();
我好像输了类型:
所以我的搜索找到了 ICommandHandler<T>
.
所以我的问题是,如何创建代表我要搜索的封闭泛型类型的 ITypeElement
?
或者:如何在返回的继承者集合中搜索以 class 作为泛型类型参数的类型?
嗯,有道理。 ITypeElement
是 IDeclaredElement
的一个实例,这意味着它有一个声明——例如 class 或接口声明。因此,当您获得代表封闭泛型的 IType
时,它由代表泛型类型 (ICommandHandler
) 的 ITypeElement
和代表已解析泛型的 ISubstitution
组成类型参数 (AnotherCommand
)。当您调用 IType.GetTypeElement()
时,它将 return 类型 element/substitution 对的类型元素部分,这是开放的泛型声明元素(因为接口声明只能是开放的)。
我认为您可能必须采用替代方法,找到 ITypeHandler<T>
的所有继承者(实现者)并在消费者中过滤它们。传递给消费者的 FindResult
可以向下转换为 FindResultInheritedElement
,这将为您提供一个已声明的元素,该元素表示实现 ITypeHandler<T>
的 class。您应该能够遍历这些元素的接口以查看它们实现了什么,并且只接受那些实现正确 T
的查找结果。我认为 TypeElementUtil
将有助于获取已声明元素的所有超类型(基本类型 + 接口)。